【问题标题】:SQL query based on condition基于条件的SQL查询
【发布时间】:2021-04-06 11:18:59
【问题描述】:

用例:我正在处理下表的 sql 查询。我的架构中有 2 个表,即cropdetails 和 translationcropdetails。 Cropdetails 保存基本的公共信息,translationcropdetails 保存多种语言的翻译。

我正在编写一个查询,该查询将返回来自 translationcropdetails 的所有记录的列表,语言 id =english_lang_id>,并返回表中存在多少种语言的记录。

   Example output:
   cropid  |  cropname    |    langid1(say eng)                           |    langid2(say spanish)          | langid3
      1       Wheat        true(if translation present for that language)   false(if translation not present)

我需要方向,我可以在写这篇文章。我不确定我是否可以继续使用case when 运算符。任何输入都将有助于实现预期结果。

 +--------------+--------------+------+-----+---------+----------------+
   | Field        | Type         | Null | Key | Default | Extra          |
   +--------------+--------------+------+-----+---------+----------------+
   | cropid       | bigint(20)   | NO   | PRI | NULL    | auto_increment |
   | cropimage    | varchar(255) | NO   |     | NULL    |                |
   | noofdays     | int(11)      | NO   |     | NULL    |                |
   +--------------+--------------+------+-----+---------+----------------+
      
   +-----------------+--------------+------+-----+---------+-------+
    | Field           | Type         | Null | Key | Default | Extra |
   +-----------------+--------------+------+-----+---------+-------+
   | trcropid        | bigint(20)   | NO   | PRI | NULL    |       |
   | cropadvice      | text         | NO   |     | NULL    |       |
   | cropattacks     | text         | NO   |     | NULL    |       |
   | cropdescription | text         | NO   |     | NULL    |       |
   | cropname        | varchar(255) | NO   |     | NULL    |       |
   | cropid          | bigint(20)   | YES  | MUL | NULL    |       |
   | languageid      | bigint(20)   | YES  | MUL | NULL    |       |
   +-----------------+--------------+------+-----+---------+-------+ 

我正在使用 Spring Boot,这是一个分页查询,我将作为本机查询执行。 目前,下面的查询将只获取英文记录列表。

   @Query(value = "select cr.* from (select cr.trcropid, cr.cropname, cr.cropid, cr.languageid from "
        + "translationcropdetails cr where cr.languageid=:languageId) cr \n#pageable\n",
        countQuery = "select count(*) from (select cr.trcropid, cr.cropname, cr.cropid, cr.languageid from "
                + "translationcropdetails cr where cr.languageid=:languageId) temp", nativeQuery = true)
public Page<Object[]> getAllCrops(@Param("languageId") Long languageId, Pageable pageable);

需要达到上述结果的方法。

【问题讨论】:

    标签: mysql sql resultset


    【解决方案1】:

    您可以尝试使用此查询,它会构建另一个查询来检索您需要的结果集。这似乎是一种奇怪的方法,但使用 MySQL 是动态构建最终查询的唯一方法,而不知道您定义了多少种语言。

        SELECT CONCAT(
            'SELECT `translationcropdetails`.cropid', GROUP_CONCAT(', `t_', REPLACE(languageid, '`', '``'), '`.trcropid IS NOT NULL AS `lang_', REPLACE(languageid, '`', '``'), '`' SEPARATOR ''),
     ' FROM `translationcropdetails` ', GROUP_CONCAT('
         LEFT JOIN `translationcropdetails`   AS `t_', REPLACE(languageid, '`', '``'), '`
                ON `translationcropdetails`.cropid = `t_', REPLACE(languageid, '`', '``'), '`.cropid
               AND `t_', REPLACE(languageid, '`', '``'), '`.languageid = ', QUOTE(languageid)
         SEPARATOR ''),
     ' GROUP BY `translationcropdetails`.cropid'
    ) FROM (SELECT DISTINCT languageid FROM `translationcropdetails`) t;
    

    如果定义了 3 种语言,这是从前一个查询构建的查询:

    SELECT
        `translationcropdetails`.cropid,
        `t_1`.trcropid IS NOT NULL AS `lang_1`,
        `t_2`.trcropid IS NOT NULL AS `lang_2`,
        `t_3`.trcropid IS NOT NULL AS `lang_3`
    FROM `translationcropdetails`
        LEFT JOIN `translationcropdetails` AS `t_1`
            ON `translationcropdetails`.cropid = `t_1`.cropid
            AND `t_1`.languageid = '1'
        LEFT JOIN `translationcropdetails` AS `t_2`
            ON `translationcropdetails`.cropid = `t_2`.cropid
            AND `t_2`.languageid = '2'
        LEFT JOIN `translationcropdetails` AS `t_3`
            ON `translationcropdetails`.cropid = `t_3`.cropid
            AND `t_3`.languageid = '3'
    GROUP BY `translationcropdetails`.cropid;
    

    您可以在SQLFiddle 中看到生成查询的结果,其中我使用了以下虚拟数据:

    -- languageid: 1 = English | 2 = Spanish | 3 = French | ...
    INSERT INTO translationcropdetails VALUES
      (1, 'adv 1', 'att 1', 'english descr', 'name 1', 1, 1),
      (2, 'adv 1', 'att 1', 'español descr', 'name 1', 1, 2),
      (3, 'adv 2', 'att 2', 'eng descr', 'name 2', 2, 1),
      (4, 'adv 2', 'att 2', 'descr en français', 'name 2', 2, 3),
      (5, 'adv 3', 'att 3', 'eng descr', 'name 3', 3, 1),
      (6, 'adv 4', 'att 4', 'eng descr', 'name 4', 4, 1),
      (7, 'adv 5', 'att 5', 'español descr', 'name 5', 5, 2),
      (8, 'adv 5', 'att 5', 'descr en français', 'name 5', 5, 3)
     ;
    

    输出将是

    cropid  lang_1  lang_2  lang_3
    ------- ------- ------- -------
    1       1       1       0
    2       1       0       1
    3       1       0       0
    4       1       0       0
    5       0       1       1
    

    【讨论】:

    • 一定会尝试这个并恢复!从我的角度来看,几乎不需要格式化,但这看起来很重要。赞一个!
    • 是的,@coderunner,你完全正确。在这个小编辑器中格式化简直太难了:D这是我的第一个答案......仍然需要改进;)
    • @coderunner,如果我的回答解决了您的问题,请随时将答案标记为已接受:) 谢谢
    • 我有。此外,作为您的第一个答案,这很好地解释了一个示例小提琴。感谢您的贡献并继续努力。
    • 你好@coderunner。问题是由于第一个 JOIN 是用“,”而不是显式 JOIN 造成的。将您的查询从FROM translationcropdetails, cropdetails 更改为FROM translationcropdetails INNER JOIN cropdetails ON translationcropdetails.cropid = cropdetails.cropid,它将起作用:)
    猜你喜欢
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 2018-10-29
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    相关资源
    最近更新 更多