簡體   English   中英

從表中選擇*,其中column =某些東西,或者,如果不可用,則column =其他

[英]select * from table where column = something or, when unavailable, column = something else

我正在尋找比隨后的查詢更有效和/或更容易閱讀的東西。 解釋問題的最好方法是提供樣本。

假設MySQL中的以下表結構代表了我正在創建的應用程序中各種字符串的本地化上下文。

create table LOCALIZATION_TABLE (
   SET_NAME    varchar(36) not null,
   LOCALE      varchar(8)  not null default '_',
   ENTRY_KEY   varhcar(36) not null,
   ENTRY_VALUE text            null
);

alter table LOCALIZATION_TABLE
  add constraint UQ_ENTRY
  unique (SET_NAME, LOCALE, ENTRY_KEY);

假設在表中輸入了以下值:

insert into LOCALIZATION_TABLE (SET_NAME, LOCALE, ENTRY_KEY, ENTRY_VALUE)
values
  ('STD_TEXT', '_',  'HELLO', 'Hello!'),
  ('STD_TEXT', '_',  'GOODBYE', 'Goodbye.'),
  ('STD_TEXT', 'ge', 'GOODBYE', 'Lebewohl')
;

我想選擇德語(“ ge”)的所有可用條目,如果不可用,則默認使用英文文本(“ _”)。 我當前使用的查詢如下:

select * from LOCALIZATION_TABLE where SET_NAME = 'STD_TEXT' and LOCALE = 'ge'
union
select * from LOCALIZATION_TABLE where SET_NAME = 'STD_TEXT' and LOCALE = '_'
  and ENTRY_KEY not in (
    select ENTRY_KEY from LOCALIZATION_TABLE where BUNDLE = 'STD_TEXT' and LOCALE = 'ge'
  )

真的不喜歡該查詢的外觀,並且我肯定必須使用一些更簡潔的方法。 任何幫助或正確方向的線索將不勝感激。 盡管這行得通,但似乎不合適

您可以提供自定義排序,然后選擇第一行,如下所示:

select * from (
    select *
    from LOCALIZATION_TABLE
    where SET_NAME = 'STD_TEXT'
    order by field(LOCALE, 'ge', '_') -- this provides the custom ordering
) x
group by ENTRY_KEY; -- this captures the first row for each ENTRY_KEY

說明:

內部選擇order by field(LOCALE, 'ge', '_')order by field(LOCALE, 'ge', '_')將按您定義的順序獲取行-在這種情況下,如果存在的話,首先顯示德語,然后顯示英語(您可以在列表中添加更多語言)。

列出非組列時(大多數服務器將其視為語法錯誤),此處的“技巧”是使用mysql的“非標准” GROUP BY行為-它僅返回為每個組找到的第一行。 外部選擇使用帶聚集的group by來獲取每個命名group by的第一行

使用您的數據查詢輸出:

+----------+--------+-----------+-------------+
| SET_NAME | LOCALE | ENTRY_KEY | ENTRY_VALUE |
+----------+--------+-----------+-------------+
| STD_TEXT | ge     | GOODBYE   | Lebewohl    |
| STD_TEXT | _      | HELLO     | Hello!      |
+----------+--------+-----------+-------------+

我認為您的查詢很好。 但是,這是另一種方法:

SELECT
      en.SET_NAME 
    , COALESCE(ge.LOCALE, en.LOCALE) 
    , en.ENTRY_KEY 
    , COALESCE(ge.ENTRY_VALUE, en.ENTRY_VALUE)
FROM 
    LOCALIZATION_TABLE AS en
  LEFT JOIN 
    LOCALIZATION_TABLE AS ge
      ON  ge.ENTRY_KEY = en.ENTRY_KEY
      AND ge.LOCALE = 'ge'
      AND ge.SET_NAME = 'STD_TEXT'
WHERE
      en.LOCALE = '_' 
  AND en.SET_NAME = 'STD_TEXT'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM