Is there a way to query different databases based on the value of a column in the query?
Say for example you have the following columns:
id
part_id
attr_id
attr_value_ext
attr_value_int
You then run a query and if the attr_id is '1' is returns the attr_value_int column but if attr_id is greater than '1' it joins data from another table based on the attr_value_ext.
something like this?
select case when a.id = 1 then a.attr_value_int
when a.id > 1 then b.some_other_col
else null end as whatever
from first_table a
left outer join other_table b
on ( a.attr_val_ext = b.id )
/
You could use a conditional in the on clause, like:
select case when attr_id = 1 then attr_value_int
when attr_id = 2 then t1.value_int
when attr_id = 3 then t2.value_int
end
from YourTable yt
left join Table1 t1
on t1.attr_id = 2 and yt.part_id = t1.part_id
left join Table2 t2
on t1.attr_id = 3 and yt.part_id = t2.part_id
This will work best if the number of tables is relatively small, and known in advance. Otherwise you'll have to resort to dynamic SQL, or building a follow up query from the client.
hard to give an exact answer based on that description...
you should be able to do that with a UNION
select stuff from one table where attr_id = 1
UNION
select stuff from another table where attr_id > 1
Nothing in the SQL spec, but there are often DB specific functions that will do this for you. For example, decode on oracle would work for you.
SELECT ID,PART_ID,ATTR_ID,CASE
WHEN attr_id =1 THEN attr_value_int
WHEN attr_id >1 THEN <SELECT QUERY>
END <My Column>
from TABLE;
Maybe this will work
Related
I want to select all rows who have same SrlNbr value and different Type in same table.
I have try many ways but did not work. Please help.
Example I want to list with ID:1,2, 5,6 and not 3,4
I have simple solution for your problem , just put your table name at the place Your_table.
Please check the query below..
SELECT a.ID
,a.SrlNbr
,a.Type
,a.[Desc]
FROM Your_Table AS a
INNER JOIN Your_Table AS b ON a.SrlNbr = b.SrlNbr
WHERE a.Type != b.Type
You can use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.SrlNbr = t.SrlNbr and t2.type <> t.type
);
If you just want srlnbrs with different types, then aggregation is convenient:
select srlnbr
from t
group by srlnbr
having min(type) <> max(type);
I have a question about my sql query. I need to exclude all the rows that have the value 'f' in it.
I have tried doing
SELECT * FROM table WHERE type NOT IN ('f')
But this doesnt seem to be working. Any help would be appreciated
EDIT: sorry for being unclear,
The problem I have is that theres multiple rows like this
name type
test1 f
test1 l
If i would use this query it would still return me test1 but what I want is that it returns NULL. Can this be done?
You apparently want to see rows where no other rows for the same name has the value f
select t1.*
from the_table t1
where not exists (select *
from the_table t2
where t1.name = t2.name
and t2.type = 'f');
If no such row exists the query will not return null it will simply return no rows at all.
Use the HAVING clause :
SELECT s.name
FROM YourTable s
GROUP BY s.name
HAVING COUNT(CASE WHEN s.type = 'f' THEN 1 END) = 0
I have a table with the following structure and Example data:
Now I want to query the records that have value equals to # and #.
For example according to the above image, It should returns 1 and 2
id
-----
1
2
Also if the parameters were #, # and $ It should give us 1. Because only the records with id 1 have all the given values.
id
-----
1
You can use a group by and having to get the distinct Id's that contain a distinct count of the number of items you're looking for
SELECT Id
FROM Table
WHERE Value IN ('#','$')
GROUP BY Id
HAVING COUNT(DISTINCT Value) = 2
SELECT Id
FROM Table
WHERE Value IN ('#','$','#')
GROUP BY Id
HAVING COUNT(DISTINCT Value) = 3
SQL Fiddle you can use this link to test
There's several ways to do this.
The subquery method:
SELECT DISTINCT Id
FROM Table
WHERE Id IN (SELECT Id FROM Table WHERE Value = '#')
AND Id IN (SELECT Id FROM Table WHERE Value = '#');
The correlated subquery method:
SELECT DISTINCT t.Id
FROM Table t
WHERE EXISTS (SELECT 1 FROM Table a WHERE a.Id = t.Id and a.Value = '#')
AND EXISTS (SELECT 1 FROM Table b WHERE b.Id = t.Id and b.Value = '#');
And the INTERSECT method:
SELECT Id FROM Table WHERE Value = '#'
INTERSECT
SELECT Id FROM Table WHERE Value = '#';
Best performance will depend on RDBMS vendor, size of table, and indexes. Not all RDBMS vendors support all methods.
Maybe a multiple self join like this?
select
distinct t1.id
from
table t1
join table t2 on (t1.id=t2.id)
join table t3 on (t1.id=t3.id)
...
where
t1.value='#' and
t2.value='#' and
t3.value='$' and
...
I have a table with columns id, product_type, product_id, quantity all as integer.
I need select data from another tables depending on product_type. For example. If product_type is 0 then select from tableA, if product_type is 1 then select from tableB etc. I tryied to find solution how to create select but unsuccessfully. Can someone help me please. I appreciate every help. Thank you.
Join the master table with the individual product tables, but use a left join and include the product_type = x filter in the join condition so that only the desired records are actually joined.
This will result in many NULL values; use coalesce to get a non-NULL value for the output:
SELECT sales.id,
sales.quantity,
sales.product_type,
coalesce(tableA.name, tableB.name) AS name,
coalesce(tableA.color, tableB.color) AS color,
tableA.numberOfAs -- is NULL for other product types
FROM sales
LEFT JOIN tableA ON sales.product_type = 0 AND
sales.product_id = tableA.product_id
LEFT JOIN tableB ON sales.product_type = 1 AND
sales.product_id = tableB.product_id
WHERE ...
Sounds like you need a CASE statement
SELECT
CASE
WHEN product_type = 1 THEN (SELECT column FROM table1 WHERE ...)
WHEN product_type = 2 THEN (SELECT column FROM table2 WHERE ...)
END
FROM table
Probably could be made more efficient by using JOINS but it would depend on your schema.
How I can select a set of rows where each row match a different condition?
Example:
Supposing I have a table with a column called name, I want the result ONLY IF the first row name matches 'A', the second row name matches 'B' and the third row name matches 'C'.
Edit:
I want to do this to work without a fixed size, but in a way I can define the sequence like R,X,V,P,T and it matches the sequence, each one in a row, but in the order.
you can, but probably not in a way you would want:
if your table has a numeric id field, that is incremented with each row, you can self join that table 3 times (lets say as "a", "b" and "c") and use the join condition a.id + 1 = b.id and b.id + 1 = c.id and put you filter in a where clause like: a.name = 'A' AND b.name = 'B' AND c.name = 'C'
but don't expect performance ...
Assuming that You know how to provide a row number to your rows (ROW_NUMBER() in SQL Server, for instance), You can create a lookup (match) table and join on it. See below for explanation:
LookupTable:
RowNum Value
1 A
2 B
3 C
Your SourceTable source table (assuming You already added RowNum to it-in case You didn't, just introduce subquery for it (or CTE for SQL Server 2005 or newer):
RowNum Name
-----------
1 A
2 B
3 C
4 D
Now You need to inner join LookupTable with your SourceTable on LookupTable.RowNum = SourceTable.RowNum AND LookupTable.Name = SourceTable.Name. Then do a left join of this result with LookupTable on RowNum only. If there is LookupTable.RowNum IS NULL in final result then You know that there is no complete match on at least one row.
Here is code for joins:
SELECT T.*, LT2.RowNum AS Matched
FROM LookupTable LT2
LEFT JOIN
(
SELECT ST.*
FROM SourceTable ST
INNER JOIN LookupTable LT ON LT.RowNum = ST.RowNum AND LT.Name = ST.Name
) T
ON LT2.RowNum = T.RowNum
Result set of above query will contain rows with Matched IS NULL if row is not matching condition from LookupTable table.
I suppose you could do a sub query for each row, but it wouldn't perform well or scale well at all and would be hard to maintain.
This may be close to what your after... but I need to know where you're getting your values for A, B, C etc...
Select [insert your fields here]
FROM
(Select T1.Name, T1.Age, RowNum as t1RowNum from T T1 order by name) T1O
Full Outer JOIN
(Select T2.Name, T2.Age, RowNum as T2rowNum From T T2 order By name) T2O
ON T1O.T1RowNum+1 = T2O.T2RowNum