SQL查询:检索具有列的每个唯一值的条目的行

时间:2014-06-03 23:58:42

标签: mysql sql

背景:

我已经针对不同的对象在三个不同的时间进行了价格搜索。这些搜索将保存在一个表格中,其中包含相应的搜索时间,对象名称和价格。

我想比较一段时间内物品的价格,但我只想在三次搜索过程中拉出价格或可用的物品。

换句话说,我希望按产品查询所有价格,但只有当该产品的所有时间段都有价格时(我不知道提前有多少时间 - 这必须确定动态地从表中。)

我的计划是使用SQL(第一次尝试SQL ......也许这不适合这项任务?)

示例数据:

+----------+----------+----------+----------+
| Time     | Item     | Price    | Dummy    |
+----------+----------+----------+----------+
| 1:00 PM  | Toy      | 100      | 1        |
| 1:00 PM  | Cola     | 200      | 2        |
| 1:00 PM  | Book     | 300      | 3        |
| 2:00 PM  | Toy      | 100      | 4        |
| 2:00 PM  | Book     | 250      | 5        |
| 3:00 PM  | Toy      | 100      | 6        |
| 3:00 PM  | Cola     | 250      | 7        |
| 3:00 PM  | Book     | 200      | 8        |
+----------+----------+----------+----------+

目标结果:

+----------+----------+----------+----------+
| Item     | 1:00 PM  | 2:00 PM  | 3:00 PM  |
+----------+----------+----------+----------+
| Toy      | 100      | 100      | 100      |
| Book     | 300      | 250      | 200      |
+----------+----------+----------+----------+

(可乐被排除在外,因为它在下午2:00搜索时不存在)

我将数据放入SQLfiddle: http://www.sqlfiddle.com/#!2/61046/1

欢迎任何见解!谢谢!

2 个答案:

答案 0 :(得分:2)

MySQL是否是必需品?在PostgreSQL(或Oracle或其他DBMS)中,我会使用类似这样的东西:

WITH better_format as (
  SELECT  a.Item, a.Time, a.Price, count(*) over ( partition by a.Item ) as distinct_times
  FROM    tableName a
  GROUP BY a.Item, a.Time, a.Price
)
SELECT * FROM better_format
WHERE distinct_times = (
  SELECT max(distinct_times) from better_format
)

您想要的输出是此的一个支点。 Oracle和PostgreSQL具有Pivot和Crosstab功能,可以准确返回您想要的内容。我不知道MySQL具有类似的能力。

SQL Fiddle

答案 1 :(得分:1)

SQL查询必须返回固定数量的列,事先已知。您无法根据数据中的次数更改列数。

你可以通过将价格连在一起来接近。然后,您希望将行保留在每次都有价格的位置。这使用having子句来计算价格数量,并与表格中time值的数量进行比较:

select item, group_concat(price order by time) as prices
from tablename
group by item
having count(price) = (select count(distinct time) from tablename)