Pesan kesalahan ini
biasanya karena definisi kolom dan tabel Anda. Ini biasanya berarti bahwa di kedua sisi tanda sama dengan ada susunan yang berbeda. Yang perlu Anda lakukan adalah memilih salah satu dan menyertakan keputusan itu dalam kueri Anda.
Masalah susunan di sini adalah di CROSS JOIN dari @prev_value yang membutuhkan susunan eksplisit untuk digunakan.
Saya juga sedikit mengubah logika "row_number" menjadi gabungan silang tunggal dan memindahkan logika if ke ekstrem daftar pilih.
Beberapa contoh data ditampilkan di bawah ini. Data sampel diperlukan untuk menguji kueri dengan. Siapa pun yang mencoba menjawab pertanyaan Anda dengan contoh kerja akan membutuhkan data. Alasan saya memasukkannya ada dua.
- agar Anda mengerti setiap hasil yang saya sajikan
- sehingga di masa mendatang ketika Anda mengajukan pertanyaan terkait SQL lainnya, Anda memahami pentingnya menyediakan data. Tidak hanya lebih nyaman bagi kami bahwa Anda melakukan ini. Jika penanya memberikan contoh data, maka penanya akan memahaminya - ini bukan penemuan orang asing yang telah mencurahkan sebagian waktunya untuk membantu.
Contoh Data
Harap perhatikan beberapa kolom hilang dari tabel, hanya kolom yang ditentukan dalam detail tabel yang disertakan.
Data sampel ini memiliki 5 komentar terhadap satu postingan (tidak ada suka yang dicatat)
CREATE TABLE Posts
(
`id` int,
`uuid` varchar(7) collate utf8_unicode_ci,
`imageLink` varchar(9) collate utf8_unicode_ci,
`date` datetime
);
INSERT INTO Posts(`id`, `uuid`, `imageLink`, `date`)
VALUES
(145, 'abcdefg', 'blah blah', '2016-10-10 00:00:00') ;
CREATE TABLE USERS
(
`id` int,
`username` varchar(15) collate utf8_unicode_ci,
`profileImage` varchar(12) collate utf8_unicode_ci,
`date` datetime
) ;
INSERT INTO USERS(`id`, `username`, `profileImage`, `date`)
VALUES
(145, 'used_by_already', 'blah de blah', '2014-01-03 00:00:00') ;
CREATE TABLE Activity
(
`id` int,
`uuid` varchar(4) collate utf8_unicode_ci,
`uuidPost` varchar(7) collate utf8_unicode_ci,
`type` varchar(40) collate utf8_unicode_ci,
`commentText` varchar(11) collate utf8_unicode_ci, `date` datetime
) ;
INSERT INTO Activity (`id`, `uuid`, `uuidPost`, `type`, `commentText`, `date`)
VALUES
(345, 'a100', 'abcdefg', 'comment', 'lah lha ha', '2016-07-05 00:00:00'),
(456, 'a101', 'abcdefg', 'comment', 'lah lah lah', '2016-07-06 00:00:00'),
(567, 'a102', 'abcdefg', 'comment', 'lha lha ha', '2016-07-07 00:00:00'),
(678, 'a103', 'abcdefg', 'comment', 'ha lah lah', '2016-07-08 00:00:00'),
(789, 'a104', 'abcdefg', 'comment', 'hla lah lah', '2016-07-09 00:00:00') ;
[Perilaku Standar SQL:2 baris per kueri Posting]
Ini adalah pertanyaan awal saya, dengan beberapa koreksi. Saya mengubah urutan kolom daftar pilih sehingga Anda akan melihat beberapa data terkait komentar dengan mudah ketika saya mempresentasikan hasilnya. Harap pelajari hasil yang disediakan sehingga Anda dapat memahami apa yang akan dilakukan kueri. Kolom yang didahului dengan # tidak ada dalam data sampel yang saya kerjakan karena alasan yang telah saya catat.
SELECT
Posts.id
, Posts.uuid
, rcom.uuidPost
, rcom.commentText
, rcom.`date` commentDate
#, Posts.caption
#, Posts.path
, Posts.`date`
, USERS.id
, USERS.username
#, USERS.fullname
, USERS.profileImage
, COALESCE(A.LikeCNT, 0) num_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
AND USERS.id = 145
LEFT JOIN (
SELECT
COUNT(A.uuidPost) LikeCNT
, A.UUIDPost
FROM Activity A
WHERE type = 'like'
GROUP BY
A.UUIDPOST
) A ON A.UUIDPost = Posts.uuid
LEFT JOIN (
SELECT
@row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number
, commentText
, uuidPost
, `date`
, @prev_value := UUIDPOST
FROM Activity
CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci ) xy
WHERE type = 'comment'
ORDER BY
uuidPost
, `date` DESC
) rcom ON rcom.uuidPost = Posts.UUID
AND rcom.row_number <= 2
ORDER BY
posts.`date` DESC
;
Lihat demonstrasi kerja kueri ini di SQLFiddle
Hasil :
| id | uuid | uuidPost | commentText | date | date | id | username | profileImage | num_likes |
|-----|---------|----------|-------------|------------------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg | abcdefg | hla lah lah | July, 09 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
| 145 | abcdefg | abcdefg | ha lah lah | July, 08 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
Ada 2 BARIS - seperti yang diharapkan. Satu baris untuk komentar terbaru, dan baris lain untuk komentar terbaru berikutnya. Ini adalah perilaku normal untuk SQL dan hingga komentar ditambahkan di bawah jawaban ini, pembaca pertanyaan akan menganggap perilaku normal ini dapat diterima.
Pertanyaannya tidak memiliki "hasil yang diharapkan" yang diartikulasikan dengan jelas.
[Opsi 1:Satu baris per kueri Posting, dengan HINGGA 2 komentar, kolom ditambahkan]
Dalam komentar di bawah ini terungkap bahwa Anda tidak ingin 2 baris per posting dan ini akan menjadi perbaikan yang mudah. Yah itu agak mudah TAPI ada opsi dan opsi ditentukan oleh pengguna dalam bentuk persyaratan. JIKA pertanyaannya memiliki "hasil yang diharapkan" maka kita akan tahu opsi mana yang harus dipilih. Meskipun demikian, inilah satu opsi
SELECT
Posts.id
, Posts.uuid
, max(case when rcom.row_number = 1 then rcom.commentText end) Comment_one
, max(case when rcom.row_number = 2 then rcom.commentText end) Comment_two
#, Posts.caption
#, Posts.path
, Posts.`date`
, USERS.id
, USERS.username
#, USERS.fullname
, USERS.profileImage
, COALESCE(A.LikeCNT, 0) num_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
AND USERS.id = 145
LEFT JOIN (
SELECT
COUNT(A.uuidPost) LikeCNT
, A.UUIDPost
FROM Activity A
WHERE type = 'like'
GROUP BY
A.UUIDPOST
) A ON A.UUIDPost = Posts.uuid
LEFT JOIN (
SELECT
@row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number
, commentText
, uuidPost
, `date`
, @prev_value := UUIDPOST
FROM Activity
CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci ) xy
WHERE type = 'comment'
ORDER BY
uuidPost
, `date` DESC
) rcom ON rcom.uuidPost = Posts.UUID
AND rcom.row_number <= 2
GROUP BY
Posts.id
, Posts.uuid
#, Posts.caption
#, Posts.path
, Posts.`date`
, USERS.id
, USERS.username
#, USERS.fullname
, USERS.profileImage
, COALESCE(A.LikeCNT, 0)
ORDER BY
posts.`date` DESC
;
Lihat kueri kedua yang berfungsi di SQLFiddle
| id | uuid | Comment_one | Comment_two | date | id | username | profileImage | num_likes |
|-----|---------|-------------|-------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg | hla lah lah | ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
** Opsi 2, gabungkan komentar terbaru ke dalam satu daftar yang dipisahkan koma **
SELECT
Posts.id
, Posts.uuid
, group_concat(rcom.commentText) Comments_two_concatenated
#, Posts.caption
#, Posts.path
, Posts.`date`
, USERS.id
, USERS.username
#, USERS.fullname
, USERS.profileImage
, COALESCE(A.LikeCNT, 0) num_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
AND USERS.id = 145
LEFT JOIN (
SELECT
COUNT(A.uuidPost) LikeCNT
, A.UUIDPost
FROM Activity A
WHERE type = 'like'
GROUP BY
A.UUIDPOST
) A ON A.UUIDPost = Posts.uuid
LEFT JOIN (
SELECT
@row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number
, commentText
, uuidPost
, `date`
, @prev_value := UUIDPOST
FROM Activity
CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci ) xy
WHERE type = 'comment'
ORDER BY
uuidPost
, `date` DESC
) rcom ON rcom.uuidPost = Posts.UUID
AND rcom.row_number <= 2
GROUP BY
Posts.id
, Posts.uuid
#, Posts.caption
#, Posts.path
, Posts.`date`
, USERS.id
, USERS.username
#, USERS.fullname
, USERS.profileImage
, COALESCE(A.LikeCNT, 0)
ORDER BY
posts.`date` DESC
Lihat kueri ketiga ini berfungsi di SQLFiddle
| id | uuid | Comments_two_concatenated | date | id | username | profileImage | num_likes |
|-----|---------|---------------------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg | hla lah lah,ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
** Ringkasan **
Saya telah menyajikan 3 kueri, masing-masing hanya menampilkan 2 komentar terbaru, tetapi setiap kueri melakukannya dengan cara yang berbeda. Kueri pertama (perilaku default) akan menampilkan 2 baris untuk setiap posting. Opsi 2 menambahkan kolom tetapi menghapus baris kedua. Opsi 3 menggabungkan 2 komentar terbaru.
Harap diperhatikan bahwa:
- Pertanyaan tidak memiliki definisi tabel yang mencakup semua kolom
- Pertanyaan tidak memiliki sampel data, yang mempersulit Anda untuk memahami hasil apa pun yang disajikan di sini, tetapi juga lebih sulit bagi kami untuk menyiapkan solusi
- Pertanyaan juga tidak memiliki "hasil yang diharapkan" yang pasti (keluaran yang diinginkan) dan ini menyebabkan kerumitan lebih lanjut dalam menjawab
Saya berharap informasi tambahan yang diberikan akan berguna, dan sekarang Anda juga tahu bahwa SQL menyajikan data sebagai beberapa baris adalah hal yang normal. Jika Anda tidak menginginkan perilaku normal tersebut, harap jelaskan apa yang sebenarnya Anda inginkan dalam pertanyaan Anda.
Nota bene. Untuk memasukkan subkueri lain untuk "mengikuti", Anda dapat menggunakan subkueri serupa dengan yang sudah Anda miliki. Itu dapat ditambahkan sebelum atau sesudah subquery itu. Anda juga dapat melihatnya digunakan di sqlfiddle di sini
LEFT JOIN (
SELECT
COUNT(*) FollowCNT
, IdOtherUser
FROM Activity
WHERE type = 'Follow'
GROUP BY
IdOtherUser
) F ON USERS.id = F.IdOtherUser
Sementara menambahkan subkueri lain dapat menyelesaikan keinginan Anda untuk informasi lebih lanjut, kueri keseluruhan mungkin menjadi lebih lambat sebanding dengan pertumbuhan data Anda. Setelah Anda menentukan fungsionalitas yang benar-benar Anda butuhkan, mungkin ada baiknya mempertimbangkan indeks apa yang Anda butuhkan pada tabel tersebut. (Saya yakin Anda akan disarankan untuk meminta saran itu secara terpisah, dan jika Anda memastikan Anda menyertakan 1. DDL lengkap tabel Anda dan 2. rencana penjelasan kueri.)