У меня есть таблица со следующими данными.
имя таблицы: myTable
prodID catNo variable1 variable2
1 20 Cat Blue
2 10 Cat Red
2 15 Cat Green
2 20 Cat Black
3 20 Cat Yellow
4 10 Cat Orange
4 15 Cat Brown
4 20 Cat Black
5 30 Cat Pink
Я хочу иметь возможность выбрать все столбцы из myTable, где верно следующее
«(prodID = 2 а также catNo = 10) А ТАКЖЕ (prodID = 2 а также catNo = 15) «. Поэтому получение результата двух строк только в том случае, если оба условия соблюдены, и ничего не будет возвращено, если обе строки отсутствуют.
Так что моя таблица результатов будет выглядеть так.
Название таблицы: результаты
prodID catNo variable1 variable2
2 10 Cat Red
2 15 Cat Green
Я пытался использовать условные операторы if, но не могу заставить их работать в SQL. Мое текущее решение — вернуть все строки с prodID = 2, а затем с помощью php выполнить оператор if, чтобы решить, что отображать, но это не сработает с нумерацией страниц, которую я разработал для отображения результатов, так как мой предел будет искажать количество результатов на странице.
Я знаю, что мог бы использовать «иметь количество строк = 2», но я не уверен, как это сформулировать.
Если вы хотите получить результаты, только если записи найдены в catNo (10,15), но также вернуть 0 результатов, если вы искали catNo в (10,12)
SELECT * FROM `myTable`
WHERE (`prodID` = 2 AND `catNo` IN (10,15))
AND (SELECT COUNT(`catNo`) FROM `myTable` WHERE `prodID` = 2 AND `catNo` IN (10,15))>1;
Для трех CatNo’s
SELECT * FROM `myTable`
WHERE (`prodID` = 4 AND `catNo` IN (10,15,20))
AND (SELECT COUNT(`catNo`) FROM `myTable` WHERE `prodID` = 4 AND `catNo` IN (10,15,20))>2;
Чтобы соответствовать обе категории для одного и того же продукта, вы можете сделать
select t.*
from table1 t
join (
select prodID
from table1
where catNo in (10,15)
and prodID = 2
group by prodID
having count(distinct catNo ) = 2
) t2
using(prodID)
where t.catNo in (10,15)
Используйте приведенный ниже SQL-запрос.
SELECT * FROM myTable where prodID = 2 and (catNo = 10 OR catNo = 15)
Надеюсь, это поможет вам
Попробуйте это, это будет работать:
SELECT * FROM `myTable` WHERE `prodID` = '2' AND `catNo` IN ('10','15')
Условие должно быть (prodID = 2 и catNo = 10) ИЛИ (prodID = 2 и catNo = 15)
SELECT DISTINCT a.*,b.catNo,c.catNo FROM myTable AS a
JOIN mytable AS b ON b.prodID=a.prodID
JOIN mytable AS c ON c.prodID=a.prodID
WHERE a.prodID=2 AND b.catNo=10
AND c.catNo=15;
этот работал. действительно сложная ситуация, эта проблема.
В большинстве опубликованных решений отсутствует часть о том, что ничего не нужно возвращать, за исключением случаев, когда выполняются условия. Таким образом, большинство решений потерпит неудачу, если будет выполнено одно-единственное условие, поскольку они по-прежнему будут возвращать одну строку вместо ни одной.
Предполагая, что вы хотите иметь возможность проверять любое количество условий WHERE, а не только два, вы можете использовать решение на основе подзапроса.
Используя этот подход, вы можете проверить количество подходящих строк в наборе результатов до вывода. Есть несколько способов сделать это, но идея состоит в том, чтобы сравнить количество подходящих строк с ожидаемым количеством строк. Если они совпадают, выведите строки. Если они не совпадают, верните пустой набор результатов.
M Khalid Junaid опубликовал решение с использованием группы с условием наличия в подзапросе, чтобы проверить, что размер результирующего набора равен 2. Это решение будет работать для вашего конкретного примера и других подобных ему. Это может не произойти, если ваши условия WHERE станут более сложными или измененными, так как он основан на том, что ProdID одинаков в каждом условии WHERE, но основной принцип — надежный. Кроме того, этот конкретный метод требует, чтобы условие WHERE обрабатывалось по отношению к исходной таблице дважды, тогда как приведенное ниже — только один раз. Для очень больших таблиц и / или многих условий WHERE этот метод должен быть более эффективным.
Вы можете создавать подзапросы либо непосредственно в условии FROM, как в других примерах, либо с помощью операторов WITH. Я использовал позже здесь, поскольку он более четко показывает, что происходит:
With ResultSet as (select * from myTable
where (prodID = 2 AND catNo = 10) OR (prodID = 2 AND catNo = 15)), -- your WHERE condition
TotalRows as (select COUNT(*) as TRows from ResultSet) -- count of result set
select ResultSet.*
from ResultSet
inner join TotalRows on 1=1 -- force the join to work no matter what the tables contain
where TRows = 2 -- this is where you check against how many result rows you expect
Подзапрос «ResultSet» — это то, к чему относится ваша причина WHERE, и она может быть настолько простой или сложной, насколько это необходимо. «TotalRows» считает результирующий набор и, следовательно, содержит только одну строку. Затем вы объединяете подзапросы вместе, но выводите только строки из первого, если количество результирующих наборов (TRows) соответствует ожидаемому размеру строки из более позднего.
Вы можете попробовать написать функцию. Это довольно долго, но довольно легко понять
DROP FUNCTION getIt();
CREATE OR REPLACE FUNCTION getIt()
RETURNS TABLE (prodID INTEGER, catNo INTEGER, variable1 TEXT, variable2 TEXT) AS
$BODY$
BEGIN
IF (CAST ((SELECT "prodID"FROM "myTable"where "prodID"=2 and "catNo" = 10) AS INTEGER)>0 AND CAST ((SELECT "prodID"FROM "myTable"where "prodID"=2 and "catNo" = 15) AS INTEGER)>0)
THEN RETURN QUERY SELECT *
FROM "myTable"where "prodID"=2 and ("catNo" = 10 or "catNo" = 15 );
END IF;
END;
$BODY$
LANGUAGE 'plpgsql';
SELECT * FROM getIt();
Может быть параметризован
DROP FUNCTION getIt(pid integer, cid1 integer, cid2 integer);
CREATE OR REPLACE FUNCTION getIt(pid integer, cid1 integer, cid2 integer)
RETURNS TABLE (prodID INTEGER, catNo INTEGER, variable1 TEXT, variable2 TEXT) AS
$BODY$
BEGIN
IF (CAST ((SELECT "prodID"FROM "myTable"where "prodID"=$1 and "catNo" = $2) AS INTEGER)>0 AND CAST ((SELECT "prodID"FROM "myTable"where "prodID"=$1 and "catNo" = $3) AS INTEGER)>0)
THEN RETURN QUERY SELECT *
FROM "myTable"where "prodID"=$1 and ("catNo" = $2 or "catNo" = $3 );
END IF;
END;
$BODY$
LANGUAGE 'plpgsql';
SELECT * FROM getIt(2, 10, 15);