I have a table with the following
Table1
col1 col2
------------
1 A
2 B
3 C
0 D
Result
col1 col2 col3
------------------
0 D ABC
I am not sure how to go about writing the query , col1 and col2 can be selected by this
select col1, col2 from Table1 where col1 = 0;
How should I go about adding a col3 with value ABC.
Try this:
select col1, col2, 'ABC' as col3 from Table1 where col1 = 0;
If you meant just ABC as simple value, answer above is the one that works fine.
If you meant concatenation of values of rows that are not selected by your main query, you will need to use a subquery.
Something like this may work:
SELECT t1.col1,
t1.col2,
(SELECT GROUP_CONCAT(col2 SEPARATOR '') FROM Table1 t2 WHERE t2.col1 != 0) as col3
FROM Table1 t1
WHERE t1.col1 = 0;
Actual syntax maybe a bit off though
Related
How to find difference of two tables based on different group: I have a below scenario:
(TABLE1
COL1=1,2,3,4,5
Table2
COL1=1,2,3,4,5
COL2=A,B,C.....
COL3=XXX OR BLANK
output
1A,1B,1C,2A,2B
)
I got the below sql but my column2 has 40 different value and it will be a big union all statement. Also the comparison needs to be done with all entries of table 1 needs to compare with table2 as A has (1,2,3 in table1 ) B has (2,3 in table2) any way to achieve it efficiently will be highly appreciated ?
Edit:
Col2 value should not be hardcoded it should be distinct value from Table2, it can be from a-z, so my below union all will have 26 statement having same code just col2 will changeenter image description here
/*SQL that is working result: */
SELECT col1
FROM table1
WHERE col1 NOT IN (
SELECT col1
FROM table2
WHERE col3 = 'xxx'
AND col2 = 'A'
)
UNION ALL
SELECT col1
FROM table1
WHERE col1 NOT IN (
SELECT col1
FROM table2
WHERE col3 = 'xxx'
AND col2 = 'B'
)
UNION ALL
SELECT col1
FROM table1
WHERE col1 NOT IN (
SELECT col1
FROM table2
WHERE col3 = 'xxx'
AND col2 = 'C'
)
Are you looking for logic like this? For your example all the col3s are the same, so:
SELECT t1.col1
FROM table1 t1
WHERE NOT EXISTS (SELECT 1
FROM table2 t2
WHERE t2.col1 = t1.col1 AND
t2.col3 = 'xxx' AND
t2.col1 IN ('A', 'B', 'C')
);
This assumes that the comparison on col3 is always 'xxx' as in your example. The logic can easily be tweaked if that is not the case.
I have multiple rows with the following columns:
col1
col2
col3
col4
I want to say if rows where col3 equals col2 of other rows where col1 equals 'a111', then sum col4 of the rows where col3 equals col2 of other rows where col1 equals 'a111', and then rename the sum column to "Total".
Example table with the four columns and four rows:
col1 col2 col3 col4
---- ---- ---- ----
a222 a333 4444
a111 a333
a555 a444 1111
a111 a444
I've tried the following but it does not work.
Declare
var1 = Select col2 from table1 where col1='a111';
var2 = Select col3 from table1 where col3=var1;
var3 = Select col4 from table1 where col3=var1;
Begin
If var2=var1
Then Select SUM(var3) As "Total";
End
Expected result is:
Total
5555
I do not have the strongest of knowledge in programming overall or Oracle. Please ask any questions and I will do my best to answer.
Your logic is convoluted and hard to follow without an example of the data you have and an example of the data you want.. but translating your pseudocode into sql gives:
Declare
var1 = Select col2 from table1 where col1='[table2.col2 value]';
Called "find" in my query
var2 = Select col3 from table1 where col3=var1;
var3 = Select col4 from table1 where col3=var1;
Achieved by joining the table back to the "find"
Begin
If var2=var1
Then Select SUM(var3) As "Total";
End
Achieved with a sum of var3 on only rows where var1=var2, in "ifpart"
SELECT SUM(var3) FROM
(
SELECT alsot1.col3 as var2, alsot1.col4 as var3
FROM
table1 alsot1
INNER JOIN
(
SELECT t1.col2 as var1
FROM table1 t1 INNER JOIN table2 t2 ON t1.col1 = t2.col2
) find
ON find.var1 = alsot1.col3
) ifpart
WHERE
var1 = var2
This could be simplified, but I present it like this because it matches your understanding of the problem. The query optimizer will rewrite it anyway when the time comes to run it so it only pays to start messing with how it's done if performance is poor
By the way, you clearly said that two tables join via a common named col2 but you then in your pseudocode said the tables join on col1=col2. I followed your pseudocode
This sounds like something that hierarchical queries could handle. E.g. something like:
WITH your_table AS (SELECT NULL col1, 'a222' col2, 'a333' col3, 4444 col4 FROM dual UNION ALL
SELECT 'a111' col1, 'a333' col2, NULL col3, NULL col4 FROM dual UNION ALL
SELECT NULL col1, 'a555' col2, 'a444' col3, 1111 col4 FROM dual UNION ALL
SELECT 'a111' col1, 'a444' col2, NULL col3, NULL col4 FROM dual UNION ALL
SELECT 'a666' col1, 'a888' col2, NULL col3, NULL col4 FROM dual UNION ALL
SELECT NULL col1, 'a777' col2, 'a888' col3, 7777 col4 FROM dual)
SELECT col1,
SUM(col4) col4_total
FROM (SELECT connect_by_root(col1) col1,
col4
FROM your_table
CONNECT BY col3 = PRIOR col2
START WITH col1 IS NOT NULL) -- start with col1 = 'a111')
GROUP BY col1;
COL1 COL4_TOTAL
---- ----------
a666 7777
a111 5555
Nevermind. I believe I've determined the answer myself. I over complicated what I wanted. Thank you anyway.
Answer:
Select Sum(col4) as "Total" from table1 where col3 in (Select col2 from table1 where col1='a111')
I need to delete the repeated row-
I have this table-
source
The result that I need-
result
*keep only one combination of 2 column (the order is not important)
Thanks! (:
Here is one method that should be efficient:
select col1, col2
from t
where col1 <= col2
union all
select col1, col2
from t
where col1 > col2 and
not exists (select 1 from t t2 where t2.col1 = t.col2 and t2.col2 = t.col1);
Note: This is a SQL select statement, so it does not delete rows in the table. You seem to want the results from a query, not to modify the underlying table.
My interpretation of the spec "keep only one combination of 2 column, [column] order not important":
SELECT col1, col2
FROM t
WHERE col1 <= col2
UNION
SELECT col2, col1
FROM t
WHERE col1 > col2;
I'm looking for a little help with a SQL query. (I am using Oracle.)
I have a query that is a union of 2 differing select statments. The resulting data looks like the following:
Col1 Col2 Col3
XXX ValA Val1
XXX ValB Val2
YYY ValA Val1
YYY ValA Val2
In this setup the Col1 = XXX are default values and Col1 = YYY are real values. Real values (YYY) should take precidence over default values. The actual values are defined via columns 2 and 3.
I'm looking to downselect those results into the following:
Col1 Col2 Col3
XXX ValB Val2
YYY ValA Val1
YYY ValA Val2
Notice that the first row was removed ... that's because there is a real value (YYY in row 3) took precidence over the default value (XXX).
Any thoughts on how to approach this?
You want to filter out all the rows where col2 and col3 appear with XXX and with another value.
You can implement this filter by doing appropriate counts in a subquery using the analytic functions:
select col1, col2, col3
from (select t.*,
count(*) over (partition by col2, col3) as numcombos,
sum(case when col1 = 'XXX' then 1 else 0 end) over (partition by col2, col3) as numxs
from t
) t
where numcombos = numxs or (col1 <> 'xxx')
My instinct is to use an analytic function:
select distinct
first_value(col1)
over (partition by col2, col3
order by case col1
when 'XXX' then 1
else 0 end asc) as col1,
col2,
col3
from table1
However, if the table is large and indexed, it might be better to solve this with a full outer join (which is possible because there are only two possible values):
select coalesce(rl.col1, dflt.col1) as col1,
coalesce(rl.col2, dflt.col2) as col2,
coalesce(rl.col3, dflt.col3) as col3
from (select * from table1 where col1 = 'XXX') dflt
full outer join (select * from table1 where col1 <> 'XXX') rl
on dflt.col2 = rl.col2 and dflt.col3 = rl.col3;
[Solution in SQLFiddle]
I think you could use a trick like this:
select
case when
max(case when col1<>'XXX' then col1 end) is null then 'XXX' else
max(case when col1<>'XXX' then col1 end) end as col1,
col2,
col3
from
your_table
group by col2, col3
I transform default value to null, then i group by col3. The maximum value between null and a value is the value you are looking for. This works on your example data, but it might not be exactly what you are looking for, it depends on how your real data is.
I have a SQLite table like this:
Col1 Col2 Col3
1 ABC Bill
2 CDE Fred
3 FGH Jack
4 CDE June
I would like to find the row containing a Col2 value of CDE which has the max Col1 value i.e. in this case June. Or, put another way, the most recently added row with a col2 value of CDE, as Col1 is an auto increment column. What is an SQL query string to achieve this? I need this to be efficient as the query will run many iterations in a loop.
Thanks.
SELECT * FROM table WHERE col2='CDE' ORDER BY col1 DESC LIMIT 1
in case if col1 wasn't an increment it would go somewhat like
SELECT *,MAX(col1) AS max_col1 FROM table WHERE col2='CDE' GROUP BY col2 LIMIT 1
Try this:
SELECT t1.*
FROM table1 t1
INNER JOIN
(
SELECT MAX(col1) MAXID, col2
FROM table1
GROUP BY col2
) t2 ON t1.col1 = t2.maxID AND t1.col2 = t2.col2
WHERE t1.col2 = 'CDE';
SQL Fiddle Demo1
1: This demo is mysql, but it should work fine with the same syntax in sqlite.
Use a subquery such as:
SELECT Col1, Col2, Col3
FROM table
WHERE Col1 = (SELECT MAX(Col1) FROM table WHERE Col2='CDE')
Add indexes as appropriate, e.g. clustered index on Col1 and another nonclustered index on Col2 to speed up the subquery.
In SQLite 3.7.11 and later, the simplest query would be:
SELECT *, max(Col1) FROM MyTable WHERE Col2 = 'CDE'
As shown by EXPLAIN QUERY PLAN, both this and passingby's query are most efficient, if there is an index on Col2.
If you'd want to see the correspondig values for all Col2 values, use a query like this instead:
SELECT *, max(Col1) FROM MyTable GROUP BY Col2