Невозможно получить всю запись с указанным условием c - PullRequest
0 голосов
/ 27 марта 2020

У меня есть две таблицы property и property_meta, таблица property содержит все записи, а property_meta содержит все элементы и детали глубины каждого свойства.

Я бы нравится искать свойство, используя следующие необязательные параметры:

  • title
  • идентификатор региона
  • идентификатор региона
  • идентификатор города

таблица property имеет следующую структуру:

| id | title | deleted
  1     test    0
  2     test2   0

и property_meta имеют такую ​​структуру:

| id | property_id | meta_key        | meta_value  
  1       1           property_area      1208
  2       1           property_region    1207
  3       1           property_city      1237
  4       2           property_area      1208
  5       2           property_region    1207
  6       2           property_city      1237

Я создал следующий запрос:

 SELECT p.* 
    FROM property p
    INNER JOIN property_meta pm ON p.id = pm.property_id 
    WHERE LOWER(p.name) LIKE concat("%%") AND p.deleted = 0 
    AND (pm.meta_key = 'property_area' AND pm.meta_value IN (1208)) 
    AND (pm.meta_key = 'property_region' AND pm.meta_value IN (1207)) 
    AND (pm.meta_key = 'property_city' AND pm.meta_value IN (1237))
    GROUP BY p.id

к сожалению, этот запрос возвращает пустой результат, но если я уберу следующие условия:

 AND (pm.meta_key = 'property_region' AND pm.meta_value IN (1207)) 
 AND (pm.meta_key = 'property_city' AND pm.meta_value IN (1237))

Я получу обе строки, какую ошибку я сделал?

Ответы [ 3 ]

1 голос
/ 27 марта 2020

Они не могут быть все действительны по одной строке, потому что при выполнении запроса предложения и являются исключительными.

Вы должны проверить, все ли три действительны одновременно, например, по сумме, как в моем примере

Так что используйте

 SELECT 
    p.id
FROM
    property p
        INNER JOIN
    (SELECT 
        `property_id`
    FROM
        property_meta pm
    GROUP BY `property_id`
    HAVING SUM(pm.meta_key = 'property_area'
        AND pm.meta_value IN (1208)) + SUM(pm.meta_key = 'property_region'
        AND pm.meta_value IN (1207)) + SUM(pm.meta_key = 'property_city'
        AND pm.meta_value IN (1237)) = 3) pm ON p.id = pm.property_id
WHERE
    LOWER(p.title) LIKE CONCAT('%%')
        AND p.deleted = 0
GROUP BY p.id
CREATE TABLE property  (
  `id` INTEGER,
  `title` VARCHAR(5),
  `deleted` INTEGER
);

INSERT INTO property 
  (`id`, `title`, `deleted`)
VALUES
  ('1', 'test', '0'),
  ('2', 'test2', '0');

CREATE TABLE property_meta  (
  `id` INTEGER,
  `property_id` INTEGER,
  `meta_key` VARCHAR(15),
  `meta_value` INTEGER
);

INSERT INTO property_meta 
  (`id`, `property_id`, `meta_key`, `meta_value`)
VALUES
  ('1', '1', 'property_area', '1208'),
  ('2', '1', 'property_region', '1207'),
  ('3', '1', 'property_city', '1237'),
  ('4', '2', 'property_area', '1208'),
  ('5', '2', 'property_region', '1207'),
  ('6', '2', 'property_city', '1237');
✓

✓

✓

✓
 SELECT 
    p.id
FROM
    property p
        INNER JOIN
    (SELECT 
        `property_id`
    FROM
        property_meta pm
    GROUP BY `property_id`
    HAVING SUM(pm.meta_key = 'property_area'
        AND pm.meta_value IN (1208)) + SUM(pm.meta_key = 'property_region'
        AND pm.meta_value IN (1207)) + SUM(pm.meta_key = 'property_city'
        AND pm.meta_value IN (1237)) = 3) pm ON p.id = pm.property_id
WHERE
    LOWER(p.title) LIKE CONCAT('%%')
        AND p.deleted = 0
GROUP BY p.id
| id |
| -: |
|  1 |
|  2 |
SELECT 
 `property_id`

FROM 
property_meta pm
GROUP BY  `property_id`
HAVING  SUM(pm.meta_key = 'property_area' AND pm.meta_value IN (1208)) +
SUM(pm.meta_key = 'property_region' AND pm.meta_value IN (1207)) +
SUM(pm.meta_key = 'property_city' AND pm.meta_value IN (1237)) = 3
| property_id |
| ----------: |
|           1 |
|           2 |

дБ <> скрипка здесь

0 голосов
/ 27 марта 2020

Вам необходимо использовать ИЛИ, а не И между необязательными параметрами. Невозможно, чтобы мета-значение строки могло быть 1207 И 1237

SELECT p.* 
    FROM property p
    INNER JOIN property_meta pm ON p.id = pm.property_id 
    WHERE LOWER(p.name) LIKE concat("%%") AND p.deleted = 0 
    AND 
    (
        (pm.meta_key = 'property_area' AND pm.meta_value IN (1208)) 
        OR (pm.meta_key = 'property_region' AND pm.meta_value IN (1207)) 
        OR (pm.meta_key = 'property_city' AND pm.meta_value IN (1237))
    )
    GROUP BY p.id
0 голосов
/ 27 марта 2020

Нет никакого способа, чтобы один из ваших рядов соответствовал всем условиям. Вы должны использовать «ИЛИ» вместо «И»:

SELECT p.* 
FROM property p
     INNER JOIN property_meta pm ON p.id = pm.property_id 
WHERE LOWER(p.name) LIKE concat("%%") AND p.deleted = 0 
      AND ((pm.meta_key = 'property_area' AND pm.meta_value IN (1208)) 
            OR (pm.meta_key = 'property_region' AND pm.meta_value IN (1207)) 
            OR (pm.meta_key = 'property_city' AND pm.meta_value IN (1237)))
GROUP BY p.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...