web-dev-qa-db-ja.com

selectステートメントを使用して子テーブルのレコード数を取得する

テーブル1のすべての列を選択しようとしているストアドプロシージャがあります。Table1の主キーを外部キーとして使用する別のテーブルがあります。この外部キーテーブルのレコード数を、次のように選択してカウントしたいと思います。

SELECT *, count(*) VacancyCount
    FROM Table1 hc
    LEFT JOIN Table2 hv
    on hc.CompanyID = hv.CompanyID  
    WHERE hc.Deleted = 0
    group by hc.CompanyID
    ORDER BY NameLang1

しかし、それはエラーを出します:

列 'dbo.Table1.NameLang1'は、集約関数にもGROUP BY句にも含まれていないため、選択リストでは無効です。

これを修正する方法を提案してください?

15
DotnetSparrow

してみてください:

select 
    *,
    (select COUNT(*) from Table2 hv where hv.CompanyID=hc.CompanyID) VacancyCount
from Table1 hc
where
    hc.Deleted = 0
order by hc.NameLang1, VacancyCount desc

新しい列を使用して注文する場合

select * from(
    select 
        *,
        CONVERT(NVARCHAR(100), (select COUNT(*) from Table2 hv where hv.CompanyID=hc.CompanyID)) VacancyCount
    from Table1 hc
    where
        hc.Deleted = 0
)x
Order by CASE WHEN @OrderByParam = 1 THEN NameLang1 ELSE VacancyCount END

提供された列NameLang1VacancyCountは同じデータ型です。

32
TechDo

あなたはグループ化を間違っています。 SELECTの '*'の代わりに、GROUP BY句でも、表1のすべての列を使用する必要があります。

または、次のような別のアプローチを試すこともできます。

SELECT *
FROM Table1 hc
LEFT JOIN (SELECT CompanyID, COUNT(*) cnt FROM Table2 GROUP BY CompanyID) hv
on hc.CompanyID = hv.CompanyID  
WHERE hc.Deleted = 0
ORDER BY NameLang1
2
ZZa

GROUP BY句のすべての列をリストする必要があります
これらの列はSELECT *ビット。

これはとにかく正しいANSI SQLです。

SELECT *自体はとにかく悪いです:列を明示的にリストする方が常に良いです

2
gbn

このようにして、列リストをグループ化してください

 SELECT column1,column2,column3..,NameLang1,count(*) VacancyCount
FROM Table1 hc
LEFT JOIN Table2 hv
on hc.CompanyID = hv.CompanyID  
WHERE hc.Deleted = 0
group by column1,column2,column3
ORDER BY NameLang1
0
Arun Kumar