2012-06-21 61 views
1

我有一个查询,我正在使用总结股票总计和显示每个股票项目更新的最后日期。我有两种不同的库存类型0和1(传入,传出)。我希望能够放在页面的底部“最近收到的股票是:”&“最后一批货是在:”。结合三个(复杂)查询

继承人什么,我有我的主要查询组,总结库存:

$query = "Select * 
      FROM (SELECT id, type, color, product, 
         SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate 
       FROM inventory 
       GROUP BY id, color, type) AS alias 
      WHERE TotalQuantity > 0"; 

现在我希望能也运行这两个查询,以抢“股票” 0最后更新的时间和1(传入,传出)

$query = "SELECT MAX(Date) FROM inventory WHERE stock = 0"; 

$query = "SELECT MAX(Date) FROM inventory WHERE stock = 1"; 

结合这三个查询的任何帮助?我在尝试联盟,但没有多少运气。

+0

SELECT id, color, type, product, SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate FROM inventory GROUP BY id, color, type HAVING SUM(Quantity) > 0 

您可以将聚合函数MAX()中结合使用条件检查查询2和3对不起,'SELECT MAX(Date)FROM inventory WHERE stock = 0'有什么复杂的? – Seph

+0

@Seph第一个复杂;)如果它是三个SELECT MAX(日期)我大概可以弄明白。 – cantaffordretail

回答

3

尝试这样:

SELECT alias.*, 
    zeroStock.zeroDate, 
    nonzeroStock.nonzeroDate 
FROM 
    (
     SELECT id, 
      type, 
      color, 
      product, 
      SUM(Quantity) AS TotalQuantity, 
      MAX(Date) AS LatestDate 
     FROM inventory 
     GROUP BY id, color, type 
    ) alias INNER JOIN 
    (
     SELECT id, MAX(Date) zeroDate 
     FROM inventory 
     WHERE stock = 0 
     GROUP BY id 
    ) zeroStock on alias.id = zeroStock.id 
    INNER JOIN 
    (
     SELECT id, MAX(Date) nonzeroDate 
     FROM inventory 
     WHERE stock = 1 
     GROUP BY id 
    ) nonzeroStock on alias.id = nonzeroStock.id 
WHERE alias.TotalQuantity > 0 
1

您可以使用CROSS JOIN的日期添加到你的正常select语句的每一行。

SELECT * 
FROM (
      SELECT * 
      FROM (
        SELECT id, type, color, product, SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate 
        FROM inventory 
        GROUP BY 
          id, color, type 
       ) AS alias 
      WHERE TotalQuantity > 0 
     ) AS q 
     CROSS JOIN (SELECT MAX(Date) AS MaxIncoming FROM Inventory WHERE stock = 0) AS r 
     CROSS JOIN (SELECT MAX(Date) AS MaxOutgoing FROM Inventory WHERE stock = 1) AS s 

Mysql Cross Join

Cross Join is also called Cartesian Product Join. The Cross Join in SQL return you a result table in which each row from the first table is combined with each rows from the second table

编辑

备案,您可以通过使用HAVING条款,而不是你的TotalQuantity的WHERE条款的简化声明。

SELECT * 
FROM (
      SELECT id, type, color, product, SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate 
      FROM inventory 
      GROUP BY 
        id, color, type 
      HAVING 
        SUM(Quantity) > 0   
     ) AS q 
     CROSS JOIN (SELECT MAX(Date) AS MaxIncoming FROM Inventory WHERE stock = 0) AS r 
     CROSS JOIN (SELECT MAX(Date) AS MaxOutgoing FROM Inventory WHERE stock = 1) AS s   
+0

看起来很有希望,但我得到一个错误:...语法使用附近'选择最大(日期)AS MaxOutgoing从库存WHERE股票= 1)AS r' – cantaffordretail

+0

@mcflause - 我的坏。我改变了陈述。你能证实吗? –

2

试试这个

Select 
    alias.id, 
    alias.type, 
    alias.color, 
    alias.product, 
    Stock0.S0, 
    Stock1.S1 
FROM (SELECT 
     id, 
     type, 
     color, 
     product, 
     SUM(Quantity) AS TotalQuantity, 
     MAX(Date)  AS LatestDate 
     FROM inventory 
     GROUP BY id, color, type) AS alias 
    left join (SELECT 
       id, 
       MAX(Date)   S0 
      FROM inventory 
      WHERE stock = 0) as Stock0 
    on Stock0.id = alias.id 
    left join (SELECT 
       id, 
       MAX(Date)   S1 
      FROM inventory 
      WHERE stock = 0) as Stock1 
    on Stock1.id = alias.id 
WHERE TotalQuantity > 0 
+0

你测试过这个查询吗? –

0
SELECT id, type, color, product, 
        SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate, null AS stock 
      FROM inventory 
      GROUP BY id, color, type 
HAVING TotalQuantity > 0 

UNION ALL 

SELECT null, null, null, null, null, MAX(Date), stock 
FROM inventory WHERE stock IN (0,1) GROUP BY stock 
0

你最好不要运行查询2和查询1查询2 3分别和3是一个单独的关注,从查询1,因为你是打算获得个人价值观而不是多列列表。同样,你在查询1中筛选结果,但在2和3中筛选结果。

当然,你可以在子查询上执行两次CROSS JOIN,但是你将在数据库和应用程序之间传输更多不必要的数据。您只需要检索两个,而不是两个整列(我可能会添加它们,与结果集的其余部分无关 - 进一步强调它的不雅感)。

此外,CROSS JOIN方法假定满足SUM(Quantity) > 0条件会有至少一排。如果它们都不满足呢? ...那么你也不会有你最新的进出库存日期!虽然可能不太可能,但这个用例必须考虑在内。

说了这么多,你可以重写你的第一个查询,以避免一个子查询:

SELECT 
    MAX(CASE WHEN stock = 0 THEN Date ELSE NULL END) AS s0_maxdate, 
    MAX(CASE WHEN stock = 1 THEN Date ELSE NULL END) AS s1_maxdate 
FROM 
    inventory