mySQL sorgu - show en popüler öğe

3 Cevap php

Ben tarihe göre gruplandırılmış bir öğenin en popüler oluşumunu bulmak ve bu maddenin adı ile birlikte tüm öğelerin toplamı görüntülemek gerekir. Tek bir sorguda olası böyle bir şey mi?

not: onlar sadece (en kolay hangisi) rastgele ya ilk ya da son olayda gösterebilir daha (takma, son 3 satır bakınız) eşit geçtiği her iseniz.

Bu sql yapılabilir yapamıyorsanız o zaman oldukça dağınık olacak gibi görünüyor hangi sonucu ile çalıştırmak zorunda ve PHP ile verileri sıralamak olacaktır.

Düzenleme: Üzgünüm, ben ''2009 '08-04 için yanlış toplam vardı. Bu 4 olmalıdır.

Ben ne gerek bir örnek:

+------------+---------------------+-------+
| date       | item                | total |
+------------+---------------------+-------+
| 2009-08-02 | Apple               |     5 |
| 2009-08-03 | Pear                |     2 |
| 2009-08-04 | Peach               |     4 |
| 2009-08-05 | Apple               |     1 |
| 2009-08-06 | Apple               |     3 |
+------------+---------------------+-------+

İşte bir örnek tablo:

CREATE TABLE IF NOT EXISTS `test_popularity` (
  `date` datetime NOT NULL,
  `item` varchar(256) NOT NULL,
  `item_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `test_popularity` (`date`, `item`, `item_id`) VALUES
('2009-08-02 00:00:00', 'Apple', 1),
('2009-08-02 00:00:00', 'Pear', 3),
('2009-08-02 00:00:00', 'Apple', 1),
('2009-08-02 00:00:00', 'Apple', 1),
('2009-08-02 00:00:00', 'Pear', 0),
('2009-08-03 00:00:00', 'Pear', 3),
('2009-08-03 00:00:00', 'Peach', 2),
('2009-08-04 00:00:00', 'Apple', 1),
('2009-08-04 00:00:00', 'Peach', 2),
('2009-08-04 00:00:00', 'Peach', 2),
('2009-08-04 00:00:00', 'Pear', 3),
('2009-08-05 00:00:00', 'Apple', 1),
('2009-08-06 00:00:00', 'Apple', 1),
('2009-08-06 00:00:00', 'Peach', 2),
('2009-08-06 00:00:00', 'Pear', 3);

3 Cevap

Benim ilk önerim oldu incorrect:

SELECT
  date, item, SUM(cnt)
FROM (
  SELECT
    date, item, count(item_id) AS cnt
  FROM test_popularity
  GROUP BY date, item_id
  ORDER BY cnt DESC
) t
GROUP BY date;

Bu yanlışlıkla (tarihe göre) dış toplama CNT tarafından emredildi iç türetilen tablonun ilk satırı seçin varsayar. Bu davranış, aslında, tanımsız ve tutarlı olması garanti değildir.

Burada doğru çözüm:

SELECT
  t1.date, t1.item, 
  (SELECT COUNT(*) FROM test_popularity WHERE date = t1.date) as total
  # see note!
FROM test_popularity t1
JOIN (
  SELECT date, item, item_id, COUNT(item_id) as count
  FROM test_popularity
  GROUP BY date, item_id
) AS t2
ON t1.date = t2.date AND t1.item_id = t2.item_id
GROUP BY t1.date;

Note:

Soru bir sorguda bu istedi çünkü ben (SELECT COUNT(*)) AS total eklendi. Bir ilişkili alt sorgu gibi Ancak, bu ölçek olmaz. Bu, her için SELECT COUNT (*) sorgu çalışacağı t1.date anlamına gelir. Kriter lütfen ve sizin ihtiyaçlarınız için uygun gerçekleştirir olmadığını görmek. Eğer değilse, o zaman ayrı bir sorguda günlük toplamları almak öneririz. Eğer uygulama bu sonuçları birleştirme olacaktır.

teşekkürler onun ilk yanıt hohodave için:

SELECT date, item, cnt, (
SELECT COUNT( * )
FROM test_popularity
WHERE date = t.date
) AS totalCnt
FROM (
SELECT date, item, count( item_id ) AS cnt
FROM test_popularity
GROUP BY date, item_id
ORDER BY cnt DESC
)t
GROUP BY date;

Bu benim alabilir olarak yakındır ....

SELECT DISTINCT p.date, ItemTotalsByDate.Item, DateTotals.Total
    FROM test_popularity p
    INNER JOIN 
(SELECT date, MAX(cnt) DayMax from
(SELECT date, item, COUNT(*) cnt
FROM dbo.test_popularity
GROUP BY date, item) tbl
GROUP BY date) MaxesByDate
    ON p. date = MaxesByDate.date
INNER JOIN 
(SELECT date, item, COUNT(*) Total FROM dbo.test_popularity
GROUP BY date, item) ItemTotalsByDate
    ON MaxesByDate.date = ItemTotalsByDate.date AND MaxesByDate.DayMax = ItemTotalsByDate.Total
INNER JOIN
(SELECT date, COUNT(*) Total FROM dbo.test_popularity
GROUP BY date) DateTotals
ON p.date = DateTotals.date

Bunu yapmak için PHP için yaprakları tek şey, sadece belirli bir tarih için bulduğu ilk sonucu görüntülemek. Ben bir kravat ne zaman keyfi bir öğe almak için iyi bir yol çözemedim. Umarım bu yardımcı olur.