如何在MySQL中循环表?

时间:2011-09-16 09:15:30

标签: mysql

我有一个包含以下架构的MySQL表:

+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| id           | int(11)     | NO   | PRI | NULL    | auto_increment |
| country_dest | int(11)     | YES  |     | NULL    |                |
| type         | varchar(56) | YES  |     | NULL    |                |
| version      | varchar(56) | YES  |     | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+

对于每个country_dest,会有几个type - 商业,旅游等(但每个country_dest可能有不同或完全独特的类型)。

我想确保对于每种类型,在每个国家/地区都有version的特定值(相同的值,例如'完整')。

例如:

+----+--------------+------------+----------+
| id | country_dest | type       | versions |
+----+--------------+------------+----------+
|  1 |            8 | business   | single   |
|  2 |            8 | business   | complete |
|  3 |            8 | tourist    | single   |
|  4 |            8 | tourist    | complete |
|  5 |            8 | diplomatic | single   |
|  6 |           14 | business   | single   |
|  7 |           14 | business   | complete |
|  8 |           14 | private    | single   |
|  9 |           31 | business   | double   |
| 10 |           31 | business   | complete |
+----+--------------+------------+----------+

如果那是表格内容,那么查询将返回:

country_dest:8,类型:外交,和 country_dest:14,类型:private

没有complete值。

输出应为:

+---------------+---------------+
| country_dest  |      type     |
+---------------+---------------+
|             8 |   diplomatic  |
|            14 |   private     |
+---------------+---------------+

在for循环中循环显示它似乎很棒,但这不是它的完成方式。我已经尝试了很多解决方案,但是我无法让它们工作,我确信必须有一种经过验证的方法来做到这一点。这是我最近的努力:

SELECT form_dest, form_vtype, form_ispack FROM _forms f
WHERE form_dest IN 
    (SELECT DISTINCT dest.form_dest FROM _forms) dest
AND form_vtype IN 
    (SELECT DISTINCT form_vtype FROM _forms as type)
AND NOT EXISTS  
    (SELECT * FROM _forms 
    WHERE f.form_dest = dest.form_dest 
    AND f.form_type = type.form_type 
    AND f.form_ispack = "Yes") 

但我收到了错误。

感谢任何帮助。欢呼声。

1 个答案:

答案 0 :(得分:2)

使用NOT EXISTS应足以获得所需的结果。

要获取整个_forms记录,您可以将语句包装到子选择中,然后使用_forms再次加入。

SQL语句

SELECT  country_dest
        , type
FROM    _forms invalid
WHERE   NOT EXISTS (        
          SELECT  country_dest
                  , type
          FROM    _forms valid
          WHERE   versions = 'complete'
                  AND valid.country_dest = invalid.country_dest
                  AND valid.type = invalid.type
        )          
GROUP BY
        country_dest
        , type

或等效使用DISTINCT

SELECT  DISTINCT country_dest
        , type
FROM    _forms invalid
WHERE   NOT EXISTS (        
          SELECT  country_dest
                  , type
          FROM    _forms valid
          WHERE   versions = 'complete'
                  AND valid.country_dest = invalid.country_dest
                  AND valid.type = invalid.type
        )          

测试脚本(SQL Server)

;WITH _forms (country_dest, type, versions) AS (
  SELECT  8, 'business', 'single'
  UNION ALL SELECT  8, 'business', 'complete'
  UNION ALL SELECT  8, 'tourist', 'single'
  UNION ALL SELECT  8, 'tourist', 'complete'
  UNION ALL SELECT  8, 'diplomatic', 'single'
  UNION ALL SELECT 14, 'business', 'single'
  UNION ALL SELECT 14, 'business', 'complete'
  UNION ALL SELECT 14, 'private', 'single'
  UNION ALL SELECT 31, 'business', 'double'
  UNION ALL SELECT 31, 'business', 'complete'
)
SELECT  country_dest
        , type
FROM    _forms f
WHERE   NOT EXISTS (        
          SELECT  country_dest
                  , type
          FROM    _forms f2
          WHERE   versions = 'complete'
                  AND f2.country_dest = f.country_dest
                  AND f2.type = f.type
        )          
GROUP BY
        country_dest
        , type