ОК, это работает достаточно хорошо:
SELECT
"Customer",
MAX(CASE WHEN "Slot" = 0 THEN "Item" END) AS "Item1",
MAX(CASE WHEN "Slot" = 1 THEN "Item" END) AS "Item2",
MAX(CASE WHEN "Slot" = 2 THEN "Item" END) AS "Item3",
MAX(CASE WHEN "Slot" = 3 THEN "Item" END) AS "Item4",
MAX(CASE WHEN "Slot" = 4 THEN "Item" END) AS "Item5"
FROM (
SELECT
l."Customer" AS "Customer",
l."Item" AS "Item",
COUNT(r."Item") / 5 AS "Ticket",
MOD(COUNT(r."Item"), 5) AS "Slot"
FROM "Orders" AS l
LEFT JOIN "Orders" AS r
ON r."Customer" = l."Customer" AND r."Item" < l."Item"
GROUP BY "Customer", "Item"
)
GROUP BY "Customer", "Ticket"
ORDER BY "Customer", "Ticket"
Это делает это:
Customer | Item1 | Item2 | Item3 | Item4 | Item5
---------|-------|-------|-------|-------|-------
Alice | ORGO | | | |
Bob | FTMCH | KLUGE | ZORP | |
Carol | BLECH | FTMCH | GLURP | KLUGE | MEEP
Carol | SQICK | ZORP | | |
Ted | FOON | SMOCK | | |
Спасибо всем, кто помог, и здесь, и на Спросите Метафильтр.
(Последующее редактирование:)
Господи, это только ухудшается: - (
Оказывается, бизнес-правила позволяют одному и тому же клиенту заказывать один и тот же товар несколько раз.и что все невыполненные заказы должны быть включены в один набор заявок. Поэтому мой игрушечный стол должен был выглядеть примерно так:
ID | Customer | Item
159 | Bob | FTMCH
264 | Bob | ZORP
265 | Bob | KLUGE
288 | Carol | FTMCH
314 | Carol | MEEP
323 | Carol | ZORP
327 | Ted | FOON
338 | Ted | SMOCK
358 | Alice | ORGO
419 | Carol | SQICK
716 | Carol | MEEP
846 | Carol | BLECH
939 | Carol | MEEP
950 | Carol | GLURP
979 | Carol | KLUGE
Несколько MEEP Кэрол искажают логику ранжирования в исходном решении, иУ меня получилось следующее отвратительное чудовище:
SELECT
"Customer",
MAX(CASE WHEN "Slot" = 0 THEN "Item" END) AS "Item0",
MAX(CASE WHEN "Slot" = 1 THEN "Item" END) AS "Item1",
MAX(CASE WHEN "Slot" = 2 THEN "Item" END) AS "Item2",
MAX(CASE WHEN "Slot" = 3 THEN "Item" END) AS "Item3",
MAX(CASE WHEN "Slot" = 4 THEN "Item" END) AS "Item4",
MAX(CASE WHEN "Slot" = 0 THEN "Quantity" END) AS "Qty0",
MAX(CASE WHEN "Slot" = 1 THEN "Quantity" END) AS "Qty1",
MAX(CASE WHEN "Slot" = 2 THEN "Quantity" END) AS "Qty2",
MAX(CASE WHEN "Slot" = 3 THEN "Quantity" END) AS "Qty3",
MAX(CASE WHEN "Slot" = 4 THEN "Quantity" END) AS "Qty4"
FROM (
SELECT
"Customer",
"Item",
COUNT("ID") AS "Quantity",
"Rank" / 5 AS "Ticket",
MOD("Rank", 5) AS "Slot"
FROM (
SELECT
main."ID" AS "ID",
main."Customer" AS "Customer",
main."Item" AS "Item",
COUNT(less."Item") AS "Rank"
FROM "Orders" AS main
LEFT JOIN (
SELECT DISTINCT
"Customer",
"Item"
FROM "Orders") AS less
ON less."Customer" = main."Customer" AND less."Item" < main."Item"
GROUP BY "ID", "Customer", "Item"
)
GROUP BY "Customer", "Item", "Rank"
)
GROUP BY "Customer", "Ticket"
, которое делает это:
Customer | Item0 | Item1 | Item2 | Item3 | Item4 | Qty0 | Qty1 | Qty2 | Qty3 | Qty3 | Qty4
Bob | FTMCH | KLUGE | ZORP | | | 1 | 1 | 1 | | |
Carol | BLECH | FTMCH | GLURP | KLUGE | MEEP | 1 | 1 | 1 | 1 | 1 | 3
Carol | SQICK | ZORP | | | | 1 | 1 | | | |
Ted | FOON | SMOCK | | | | 1 | 1 | | | |
Alice | ORGO | | | | | 1 | | | | |
Я думаю, это делает свою работу, но мне очень повезло, чтобаза данных всегда будет очень маленькой (несколько тысяч строк).
Духовно, я парень по встраиваемым системам, а не парень по базе данных. Может ли кто-нибудь, кто делает это для жизни, сказать мне, является ли этоерунды это обычное дело? Будет ли запрос с четырьмяsted SELECTs и LEFT JOIN заслуживают упоминания в Daily WTF?