How to retrieve data based on multiple conditions from multiple rows from two joined tables? - sql

[Table 1]
[Table 2]
[select *]
SELECT
product.xid as xid,
product.option_group_id as option_group_id,
product.brand_id as brand_id
FROM product_promotion as product
LEFT JOIN product_promotion_to_filters as filters
ON(filters.product_xid = product.xid)
WHERE (filters.options_xid = '04320095' and filters.value_xid = '50073608') and (filters.options_xid = '85047331' and filters.value_xid = '77933356')
No value is returned. empty query
My problem with the where part. Value does not match because multiple rows are returned
The result I want in the condition section is to only get the matching records from multiple preferences.
WHERE (filters.options_xid = '04320095' and filters.value_xid = '50073608') and (filters.options_xid = '85047331' and filters.value_xid = '77933356')
As a result of this query, I want only the data with xid 27145569 to come
Since there is no data in one row, I can only make one condition, but sometimes 2-3 or more conditions need to be matched.
This is how I found the solution.
WHERE CONCAT(filters.options_xid,filters.value_xid) IN ('0432009550073608', '8504733163299671') HAVING COUNT(product.xid) >= 2;

You can use IN command to filter the result in WHERE clause.
Let me know if it works.

Related

Comparing multiple row and columns in sql server

I had two tables first one is the real table second one is the temporary. I had to compare this two table . First table had 'KartelaKod' field should match with temp's 'KartelaKodu' field, First's 'OzellikKod' field should match with temp's 'OzellikKodu',first's 'AltKod' field should match with temp's 'StokKodu'.
Finally if it doesn't match exactly it should return ''.
PS: You should have to group first table according to VrtUrunKod.
In example if MAM|002's (which is VrtUrunKod) OzellikKod field doesn't match with temp table's OzellikKodu field, it should look for another VrtUrunKod record.
Edit1:isnull((Select TOP 1 VrtUrunKod From KonfigOlusmusOzellikler k Where Sirket_Kod = #sp_Sirket_Kod and AnaUrunKod = #spStokKod and
exists(Select * From #TempDegisen t Where t.KartelaKodu = k.KartelaKodu and t.OzellikKodu = k.OzellikKod and t.StokKodu = k.AltKod)),'') this is what i written so far you can ignore Sirket_Kod field and parameter.
This should produce a list of rows where there is a k with no matching t, and at with no matching k. If no rows result, all rows are matched:
SELECT *
FROM
KonfigOlusmusOzellikler k
FULL OUTER JOIN
#TempDegisen t
ON
t.KartelaKodu = k.KartelaKodu and
t.OzellikKodu = k.OzellikKod and
t.StokKodu = k.AltKod
WHERE t.KartelaKodu IS NULL OR k.KartelaKodu IS NULL

SQL Query - Distinct doesn't seem to filter

I'm utilizing four separate tables and i can't seem to figure out why my DISTINCT isn't filtering the results. I'm trying to get a single result for each acct.Name in this query. Regardless if i use DISTINCT or not, i get the exact same results.
Select DISTINCT
acct.Name,
inv.InvoiceNumber,
acct.AccountNumber,
addr.Line1,
addr.Line2,
addr.Line3,
addr.City,
addr.StateOrProvince,
addr.postalcode
FROM InvoiceBase inv, AccountBase acct
JOIN AccountExtensionBase base
ON base.AccountId = acct.AccountId
JOIN CustomerAddressBase addr
ON addr.ParentId = acct.AccountId
WHERE
inv.AccountId=acct.AccountId And
base.New_cocat_master = 1 And
base.New_CompanyId = 1 And
inv.StateCode = 0 And
inv.Name = '2013 ' + acct.AccountNumber
ORDER by acct.Name
The first result i get now has the first three values (acct.Name, inv.InvoiceNumnber, acct.AccountNumber) and the rest of the columns are blank. The second row has all of the columns with the information. I'm just trying to make the acct.Name to be DISTINCT
The rows are DISTINCT
This may be confusing when you are selecting multiple strings, since there might be hidden characters/spaces. Select the length of each one of those fields and compare the so called duplicate rows.
Turns out all i had to do was add in a simple clause in the WHERE, since the address is required for a valid invoice (where to send it):
WHERE
base.New_cocat_master = 1 And
base.New_CompanyId = 1 And
inv.StateCode = 0 And
inv.Name = '2013 ' + acct.AccountNumber And
addr.Line1 IS NOT NULL

Creating filter with SQL queries

I am trying to create a filter with SQL queries but am having trouble with numeric values linking to other tables.
Every time I try to link to another table, it takes the same record and repeats it for every element in the other table.
For example, here is query:
SELECT ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID AND
ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0
The last line is the actual filtering criteria.
Here is an example result:
There should only be ONE result (Item has an RID of 0). But it's repeating a copy of the one record for every result inside the substitution groups table (there's 4).
Here is my database schema for reference. The lines indicate relationships between tables and the circles indicate the values I want:
You're forgot to join between ELEMENTS and SUBSTITUTION_GROUPS in your query.
SELECT
ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM
ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE
ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID
AND ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = SUBSTITUTION_GROUPS.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0

MySQL Join from multiple options to select one value

I am putting together a nice little database for adding values to options, all these are setup through a map (Has and Belongs to Many) table, because many options are pointing to a single value.
So I am trying to specify 3 option.ids and a single id in a value table - four integers to point to a single value. Three tables. And I am running into a problem with the WHERE part of the statement, because if multiple values share an option there are many results. And I need just a single result.
SELECT value.id, value.name FROM value
LEFT JOIN (option_map_value, option_table)
ON (value.id = option_map_value.value_id AND option_map_value.option_table_id = option_table.id)
WHERE option_table.id IN (5, 2, 3) AND value.y_axis_id = 16;
The problem with the statement seems to be the IN on the WHERE clause. If one of the numbers are different in the IN() part, then there are multiple results - which is not good.
I have tried DISTINCT, which again works if there is one result, but returns many if there is many. The closest we have gotten to is adding a count - to return to value with the most options at the top.
So is there a way to do the WHERE to be more specific. I cannot break it out into option_table.id = 5 AND option_table.id = 2 - because that one fails. But can the WHERE clause be more specifc?
Maybe it is me being pedantic, but I would like to be able to return just the single result, instead of a count of results... Any ideas?
The problem with the statement seems to be the IN on the WHERE clause. If one of the numbers are different in the IN() part, then there are multiple results - which is not good. I have tried DISTINCT, which again works if there is one result, but returns many if there is many. The closest we have gotten to is adding a count - to return to value with the most options at the top.
You were very close, considering the DISTINCT:
SELECT v.id,
v.name
FROM VALUE v
LEFT JOIN OPTION_MAP_VALUE omv ON omv.value_id = v.id
LEFT JOIN OPTION_TABLE ot ON ot.id = omv.option_table_id
WHERE ot.id IN (5, 2, 3)
AND v.y_axis_id = 16
GROUP BY v.id, v.name
HAVING COUNT(*) = 3
You were on the right track, but needed to use GROUP BY instead in order to be able to use the HAVING clause to count the DISTINCT list of values.
Caveat emptor:
The GROUP BY/HAVING COUNT version of the query is dependent on your data model having a composite key, unique or primary, defined for the two columns involved (value_id and option_table_id). If this is not in place, the database will not stop duplicates being added. If duplicate rows are possible in the data, this version can return false positives because a value_id could have 3 associations to the option_table_id 5 - which would satisfy the HAVING COUNT(*) = 3.
Using JOINs:
A safer, though more involved, approach is to join onto the table that can have multiple options, as often as you have criteria:
SELECT v.id,
v.name
FROM VALUE v
JOIN OPTION_MAP_VALUE omv ON omv.value_id = v.id
JOIN OPTION_TABLE ot5 ON ot5.id = omv.option_table_id
AND ot5.id = 5
JOIN OPTION_TABLE ot2 ON ot2.id = omv.option_table_id
AND ot2.id = 2
JOIN OPTION_TABLE ot3 ON ot3.id = omv.option_table_id
AND ot3.id = 3
WHERE v.y_axis_id = 16
GROUP BY v.id, v.name

Return master rows based on detail filter

I have a query where I want to return Master rows based on whether the detail fulfil a certain criteria.
For example, I only want to return a particular Master row if AT LEAST one of the Detail rows have SomeProperty = X.
Based on the following predicate:
predicate = predicate.And(p =>
p.BasketItems.Where(obi => obi.BasketItemTypeID ==
(int) BasketType.Refund).Count() > 0);
generates the following SQL:
SELECT COUNT(*)
FROM [dbo].[BasketItems] AS [t3]
WHERE ([t3].[BasketId] = [t0].[OrderBasketID]) AND ([t3].[BasketItemTypeID] = 3)
)) > 0)
Problem with this is it's doing a table scan, so the query takes a while to run.
Just checking that I'm not doing anything crazy and wonder if there's anything that can speed up this query?
Thanks
Duncan
select M.basketID, max(M.field1) as field1, max(M.field2) as field2
from dbo.basketItems as M
Inner join detail on M.basketID = detail.basketID
where detail.basketItemTypeID = '3'
group by M.basketID
(Join master to detail. select all rows where detail has the required criterion. Squish the resulting rows down to 1 per master record.)