mysql - 基于条件的SQL查询

标签 mysql sql resultset

用例:我正在对下表进行 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,这是一个分页查询,我将作为 native 查询执行。 目前,以下查询将仅获取英文记录列表。

   @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 是动态构建最终查询的唯一方法,而无需知道您定义了多少种语言。

    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

关于mysql - 基于条件的SQL查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66967656/

相关文章:

mySQL如何防止插入除非两列(字段)的组合是唯一的?

java - Oracle Java SQL异常错误: ORA-0094

java - 即使行存在,executeQuery Mysql - Java 中的 ResultSet 也为 false

java - 如何使用Java ResultSet将结果转换为String

php - 我无法从数据库中检索值

mysql - Openquery 插入不起作用

php - 在 php 变量中添加来自 sql 数据库的多列值(不使用 html 复选框标记中的数组名称)

mysql - 从多个表中删除行

Java ResultSet getString 怪异?

Javascript 与 MySQL 数据库交互