2 つのテーブルの行をカウントしたいので、次のコードを書きました。
SELECT count(v.id), count(c.id)
FROM votes as v, content as c
WHERE v.user_id=1 AND c.created_by=1
1 つの行と 2 つの列を正しく返しますが、これら 2 つのセルだけがまったく同じ値を持ちます...そしてそうであってはなりません
2 つのテーブルの行をカウントしたいので、次のコードを書きました。
SELECT count(v.id), count(c.id)
FROM votes as v, content as c
WHERE v.user_id=1 AND c.created_by=1
1 つの行と 2 つの列を正しく返しますが、これら 2 つのセルだけがまったく同じ値を持ちます...そしてそうであってはなりません
クエリは、2 つのテーブル間でクロス結合を行っています。行を数えたい場合は、次のようなものが必要です。
select 'vote' as which, count(*)
from votes v
where v.user_id = 1
union all
select 'content' as which, count(*)
from content c
where c.created_by = 1
1 行 2 列を探している場合は、代わりにクロス結合を使用します。
select vcnt, ccnt
from (select count(*) as ccnt
from votes v
where v.user_id = 1
) v cross join
(select count(*) as ccnt
from content c
where c.created_by = 1
) c
NULL
個別の値をカウントする必要があります。それ以外の場合は、それぞれの列に ID を含む行の数をカウントするだけです (一部の ID に s がある場合を除いて、すべての行になります)。
count(DISTINCT v.id), count(DISTINCT c.id)
SELECT
COUNT(Votes.id) VotesCount,
COUNT(Content.id) ContentCount
FROM
Votes
FULL OUTER JOIN Content ON 1=2 --Ensures rows never join
これにより、2 つのテーブルが結合されますが、どの行とも一致しません。したがって、Votes の各行では、すべての Content 列が NULL になり、その逆も同様です。COUNT(ColumnName) は NULL 値をカウントしませんが、COUNT(*) はカウントします。したがって、これにより結果が得られるはずです。
UNION ALL
同じ行にデータが必要な場合は、CASE
ステートメントを使用できます。
select max(case when col = 'voteCount' then cnt end) as voteCount,
max(case when col = 'ContentCount' then cnt end) as ContentCount
from
(
select count(*) cnt, 'voteCount' col
from votes v
where v.user_id = 1
union all
select count(*) cnt, 'ContentCount' col
from content c
where c.created_by = 1
) x
選択した ID が null でない場合のみカウントする
SELECT SUM(ISNULL(v.id,0,1)), SUM(ISNULL(c.id,0,1))
FROM votes as v, content as c
WHERE v.user_id=1 AND c.created_by=1
ただし、個別にカウントする必要がある場合は、これに従ってください。
SELECT
(SELECT COUNT(*) FROM votes as v WHERE v.user_id=1) AS Count1,
(SELECT COUNT(*) FROM content as c WHERE c.created_by=1) AS Count2