SQLite dummy value in select output on empty table - sqlite

I have a SQLite database with this sample table:
CREATE TABLE PROVA
(
c1 TEXT NOT NULL UNIQUE,
c2 TEXT NOT NULL,
c3 TEXT NOT NULL
);
This table will be empty at certain times (e.g. during initialization) and I need a query which can return an output like this without having to specify the columns name (a dummy value for every column).
c1 c2 c3
-------- -------- --------
dummy dummy dummy

We could use a union trick here with the help of RANK:
WITH cte AS (
SELECT c1, c2, c3, 1 AS pos FROM PROVA
UNION ALL
SELECT 'dummy', 'dummy', 'dummy', 2
),
cte2 AS (
SELECT c1, c2, c3, RANK() OVER (ORDER BY pos) rn
FROM cte
)
SELECT c1, c2, c3
FROM cte2
WHERE rn = 1;

Related

Oracle SQL: Self join and self lookup

Need help. I am putting my requirement in simple steps here. I have a data like below.
with x as (
select 'a=x AND b=y AND c=z' C1, 'a' C2, '100' C3 from dual union all
select 'a=x AND b=y AND c=z' C1, 'b' C2, '200' C3 from dual union all
select 'a=x AND b=y AND c=z' C1, 'c' C2, '300' C3 from dual union all
select 'a=x AND d=y AND c=z' C1, 'd' C2, '400' C3 from dual union all
select 'a=x AND e=y AND c=z' C1, 'e' C2, '500' C3 from dual
)
select * from x;
My output looks like below:
C1 C2 C3
------------------------------
a=x AND b=y AND c=z a 100
a=x AND b=y AND c=z b 200
a=x AND b=y AND c=z c 300
a=x AND d=y AND c=z d 400
a=x AND e=y AND c=z e 500
I am looking for a query to get the output like below. I have a condition in one column (C1), Also I have look-up data in same table in different columns (C2 and C3). I want to replace the values in C1 if any of the string exists in column C2 with the value from column C3.
100=x AND 200=y AND 300=z a 100
100=x AND 200=y AND 300=z b 200
100=x AND 200=y AND 300=z c 300
100=x AND 400=y AND 300=z d 400
100=x AND 500=y AND 300=z e 500
My exact requirement is, I have a table with a column contains WHERE condition (C1) like above. They used business column names in condition and there is second column with business name (C2) and there is third column with actual physical column name in DB (C3) in the same table. I am looking for the query which can replace the business names in C1, by looking at column C2 with the corresponding value in column C3.

sqlite select difference between 2 tables

table1 has columns A1,B1,C1 and table2 has columns A2,B2,C2 where A1 and A2 refer to the same thing, and B1 and B2 refer to the same thing.
How do I find rows in table1 such that the equivalent rows in table2 (A2=A1, B2=B1) are not in table1, and vice versa?
is it an EXCEPT?
You can use NOT EXISTS like
select A1, B1, C1
from table1
where not exists
(
select 1 from table2
where A2 = table1.A1
and B2 = table1.B1
)

select rowid of certain row when using group by in sqlite

I have a query in SQLite where I group by a certain column and use an aggregate function MAX on another column in the select statement. Now I also want the rowid of the row which holds the value that is displayed by the MAX aggregate. I know that this must be a unique row because of the primary key constraint. I can't figure out how to write the query. See the following example:
create table t1 (c1, c2, constraint t1_pk primary key (c1, c2));
insert into t1 values ('boys', 1);
insert into t1 values ('boys', 2);
insert into t1 values ('girls', 1);
insert into t1 values ('girls', 2);
Now I have the table with the primary constraint over both columns. A SELECT query for the table gives the following output:
sqlite> select rowid, * from t1;
rowid|c1|c2
1|boys|1
2|boys|2
3|girls|1
4|girls|2
Now I want to group by c1 and select the MAX of c2. Then I want the rowid of the row which holds the values displayed now. See the following queries:
sqlite> select rowid, c1, max(c2) from t1 group by c1;
rowid|c1|max(c2)
2|boys|2
4|girls|2
sqlite> select rowid, c1, min(c2) from t1 group by c1;
rowid|c1|min(c2)
2|boys|1
4|girls|1
The second query with the MIN aggregate should return the rowids of the rows holding the MIN values, this is what I want to achieve:
rowid|c1|min(c2)
1|boys|1
3|girls|1
Now I've tried the following subselect, which doesn't work either because it gives an error:
sqlite> select (select rowid from t1 b where b.c1 = a.c1 and b.c2 = max(a.c2)), a.c1, max(a.c2) from t1 a group by a.c1;
Error: misuse of aggregate function max()
sqlite> select (select rowid from t1 b where b.c1 = a.c1 and b.c2 = min(a.c2)), a.c1, min(a.c2) from t1 a group by a.c1;
Error: misuse of aggregate function min()
The last thing I've tried is a subquery in the FROM clause, which also doesn't work:
sqlite> select
...> (select rowid from t1 b where b.c1 = c.c1 and b.c2 = c.c2),
...> c1,
...> c2
...> from
...> (select a.c1, max(a.c2) as c2 from t1 a group by a.c1) c;
Error: misuse of aggregate: max()
sqlite> select
...> (select rowid from t1 b where b.c1 = c.c1 and b.c2 = max(c.c2)),
...> c.c1,
...> max(c.c2)
...> from
...> (select a.c1, a.c2 from t1 a group by a.c1) c;
Error: misuse of aggregate function max()
Is there any solution for my problem? I really don't know what else I could try.
If I understood your question correctly, try like this:
select rowid, c1, min(c2) from t1 a
where c2=(select min(c2) from t1 b where b.c1=a.c1)
group by rowid,c1;
check the FIDDLE
Indeed, following the answer by #Pradeeshnarayan, I have been obliged to improve it to make it work in Oracle.
"Group by" clause is useless
select rowid, c1, c2 from t1 a
where c2=(select min(c2) from t1 b where b.c1=a.c1);

How can I rewrite a multi-column IN clause to work on SQLite?

I've got a query that looks something like this:
SELECT
*
FROM table
WHERE
(col1, col2) in (
('col1_val1', 'col2_val1'),
('col1_val2', 'col2_val2'),
('col1_val3', 'col2_val3'),
)
This works in MySQL, but fails in sqlite3 with a syntax error:
Error: near ",": syntax error
How can I rewrite this query to an equivalent one that works in sqlite3?
Choose your favourite version:
http://sqlfiddle.com/#!5/6169b/9
using temporary table
CREATE TEMPORARY TABLE pair (a INTEGER, b INTEGER);
INSERT INTO pair (a, b) VALUES (1, 1);
INSERT INTO pair (a, b) VALUES (2, 2);
....
data IN pairs; if pair(a,b) is not unique
SELECT *
FROM data
WHERE EXISTS (
SELECT NULL
FROM pair
WHERE pair.a = data.a
AND pair.b = data.b
);
data IN pairs; if pair(a,b) is unique
SELECT data.*
FROM data
INNER JOIN pair
ON pair.a = data.a
AND pair.b = data.b;
data NOT IN pairs; if pair(a,b) is unique
SELECT data.*
FROM data
LEFT JOIN pair
ON pair.a = data.a
AND pair.b = data.b
WHERE pair.a IS NULL
OR pair.b IS NULL;
using inline table
data IN pairs; if pair(a,b) is not unique
SELECT *
FROM data
WHERE EXISTS (
SELECT NULL
FROM (
SELECT 1 AS a, 1 AS b
UNION ALL
SELECT 2 AS a, 2 AS b
UNION ALL
SELECT 3 AS a, 3 AS b
) AS pair
WHERE pair.a = data.a
AND pair.b = data.b
);
data IN pairs; if pair(a,b) is unique
SELECT data.*
FROM data
INNER JOIN (
SELECT 1 AS a, 1 AS b
UNION ALL
SELECT 2 AS a, 2 AS b
UNION ALL
SELECT 3 AS a, 3 AS b
) AS pair
ON pair.a = data.a
AND pair.b = data.b;
data NOT IN pairs; if pair(a,b) is unique
SELECT data.*
FROM data
LEFT JOIN (
SELECT 1 AS a, 1 AS b
UNION ALL
SELECT 2 AS a, 2 AS b
UNION ALL
SELECT 3 AS a, 3 AS b
) AS pair
ON pair.a = data.a
AND pair.b = data.b
WHERE pair.a IS NULL
OR pair.b IS NULL;
Here's an easy solution that works, but it might not perform well on large data sets because it can't use any of your indexes.
SELECT * FROM table
WHERE col1 || '-' || col2 in (
'col1_val1-col2_val1',
'col1_val2-col2_val2',
'col1_val3-col2_val3'
)
Try it in sqlfiddle
Enjoy!
In sqlite try to add the VALUES keyword:
SELECT *
FROM table
WHERE
(col1, col2) in ( VALUES --> add this keyword and remove the last ,
('col1_val1', 'col2_val1'),
('col1_val2', 'col2_val2'),
('col1_val3', 'col2_val3')
)
Basically in sqLite executing the query:
VALUES
('col1_val1', 'col2_val1'),
('col1_val2', 'col2_val2');
is the same as:
SELECT 'col1_val1' AS column1, 'col2_val1' AS column2
UNION
SELECT 'col1_val2' AS column1, 'col2_val2' AS column2;
or combined:
SELECT 'col1_val1' AS column1, 'col2_val1' AS column2
UNION VALUES ('col1_val2', 'col2_val2');
So you could even write it like:
SELECT *
FROM table
WHERE (col1, col2) IN (
SELECT 'col1_val1', 'col2_val1'
UNION
SELECT 'col1_val2', 'col2_val2'
);
which is a simple subquery and works in all/most databases.

How to block returning a resultset from stored procedure?

I have a stored procedure that returns multiple resultsets, it looks something like this
BEGIN
SET NOCOUNT ON;
SELECT c1, c2, c3
FROM t1
WHERE id = #id
IF (##ROWCOUNT = 0)
BEGIN
SELECT c1, c2, c3
FROM t2
WHERE id = #id
END
END
I use this stored procedure in my front-end ASP.NET website.
If the first SELECT statement did not return any rows I get 2 resultsets (1st one is obviously empty) in my SqlDataReader. Is there a way to return only the resultset from the last SELECT statement?
Couple of options you could take here, you'd have to test in your environment to see which works best.
First option would be to wrap the first statement in an if block similar to what you've done with the second block:
BEGIN
SET NOCOUNT ON;
if exists
(
SELECT c1, c2, c3
FROM t1
WHERE id = #id
)
begin
SELECT c1, c2, c3
FROM t1
WHERE id = #id
end
else
begin
SELECT c1, c2, c3
FROM t2
WHERE id = #id
END
END
Second option would be to use a temp table/variable:
BEGIN
SET NOCOUNT ON;
declare #t1 table (c1 int, c2 int, c3 int)
insert #t1 (c1,c2,c3)
SELECT c1, c2, c3
FROM t1
WHERE id = #id
IF (##ROWCOUNT = 0)
BEGIN
SELECT c1, c2, c3
FROM t2
WHERE id = #id
END
ELSE
BEGIN
select c1,c2,c3
from #t1
end
END
In a slightly different approach from the other good answers, you can use a union:
SELECT c1, c2, c3 FROM t1 WHERE id = #id
UNION ALL
SELECT c1, c2, c3 FROM t2 WHERE id = #id
AND NOT EXISTS (
SELECT * FROM t1 WHERE id = #id
)
DECLARE #Count int;
SELECT #Count = Count(*)
FROM t1
WHERE id = #id
IF(#Count = 0)
BEGIN
SELECT c1, c2, c3
FROM t2
WHERE id = #id
END
ELSE
BEGIN
SELECT c1, c2, c3
FROM t1
WHERE id = #id
END
Keep it simple:
BEGIN
SET NOCOUNT ON;
if exists (SELECT 1 FROM t1 WHERE id = #id)
SELECT c1, c2, c3
FROM t1
WHERE id = #id
else
SELECT c1, c2, c3
FROM t2
WHERE id = #id
END
;
WITH
rws_1 AS(
SELECT c1, c2, c3 FROM t1 WHERE id = #id
),
rws_2 AS(
SELECT c1, c2, c3 FROM t2 WHERE id = #id
)
SELECT * FROM rws_1
UNION ALL
SELECT * FROM rws_2 WHERE NOT EXISTS(SELECT * FROM rws_1)

Resources