选择按NULLABLE列

时间:2018-02-02 16:19:56

标签: mysql sql

我有一张桌子' localization_string '保存应用程序本地化的字符串。它曾经用于为多个应用程序保存字符串("提供商")。字符串有一个上下文(显示它们的位置)。某些字符串具有数字提供者ID,某些字符串的提供者ID为NULL(这些是"默认"字符串)。某些上下文是使用多个提供程序指定的(在单独的行中)。

我想获取特定提供商的所有字符串。这包括所有"默认"字符串,但是当使用provider id指定上下文时,则必须选择此字符串。

我有这个简化的表格结构作为插图:

  • context,varchar,not null
  • provider_id,number,null

一些简化的示例行可能如下所示:

id   context                | provider_id
----------------------------+------------
1    common.contract.header | NULL    
2    common.contact.address | NULL
3    webcalc.home.title     | NULL
4    webcalc.home.title     | 1
5    webcalc.home.title     | 2

因此,对于提供者1,我想获得字符串ID 1,2,4。不是#3,因为provider_id 1是使用相同的上下文而不是#2指定的,因为它与#1不同。

---编辑---

这是' localization_string':

的CREATE TABLE命令
CREATE TABLE `localization_string` (
  `localization_string_id` int(11) NOT NULL AUTO_INCREMENT,
  `context` varchar(255) NOT NULL,
  `value` varchar(255) NOT NULL,
  `entity_created` datetime NOT NULL,
  `entity_version` int(11) NOT NULL,
  `locale` int(11) NOT NULL,
  `provider` int(11) DEFAULT NULL,
  PRIMARY KEY (`localization_string_id`),
  KEY `fk_19cf27dcf987735b3f92dcbe7e2` (`locale`),
  KEY `fk_2b9de3a0dacbfae475f526c12d0` (`provider`),
  KEY `ind_be3921786d4fef28d84f42c24a2` (`context`,`locale`,`provider`),
  CONSTRAINT `fk_19cf27dcf987735b3f92dcbe7e2` FOREIGN KEY (`locale`) REFERENCES `locale` (`locale_id`),
  CONSTRAINT `fk_2b9de3a0dacbfae475f526c12d0` FOREIGN KEY (`provider`) REFERENCES `contract_provider` (`contract_provider_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

非常感谢您的帮助,因为我无法理解这一点。

3 个答案:

答案 0 :(得分:4)

好的,我更了解你要做的事情。

这是一个解决方案:

SELECT
  COALESCE(p.localization_string_id, d.localization_string_id) AS localization_string_id,
  d.context
FROM localization_string AS d
LEFT OUTER JOIN localization_string AS p
 ON d.context = p.context AND p.provider = ?
WHERE d.provider IS NULL;

表引用d用于默认字符串,我假设每个上下文总是会有一个默认条目。

表引用p用于给定提供程序的可选字符串。 p.provider=?上的条件必须在连接条件中,而不是WHERE子句。如果该提供程序的给定上下文没有行,则外部联接将返回所有NULL。

然后COALESCE()函数返回p的特定行(如果匹配)。如果没有,它将默认为d的默认行。

答案 1 :(得分:0)

所以我的情况与此相似。我还没有找到一种方法,除了编写某种脚本或查询后,查看表格,看看是否有一个非null的provider_id。类似的东西:

SELECT *
FROM test_tbl t
WHERE 1 = (CASE
           WHEN provider_id IS NULL AND (SELECT 'Y'
                                         FROM test_tbl x
                                         WHERE x.context=t.context
                                         AND x.app=t.app
                                         AND x.provider IS NOT NULL) = 'Y'
              THEN 0
            ELSE 1)
group by app, context, provider_id;

我是group_by&ed;因为我不知道是否可能有多行' null'或者' 1'。不确定这是否可以正常工作,因为我无法测试,但可能类似。

答案 2 :(得分:0)

我想出了一个解决方案:

SELECT 
    cp.context,
    cp.value
FROM
(
SELECT context, value
FROM localization_string
WHERE context LIKE 'common.%' 
    OR (context LIKE 'webcalc-v2.%' AND provider = 1)
) AS cp
INNER JOIN localization_string l
    ON cp.context = l.context
WHERE (l.context LIKE 'common.%' OR l.context LIKE 'webcalc-v2.%')
AND provider IS NULL

欢迎更多优化解决方案及解释......