Where condition with integer values return same as ir were a string - apache-spark-sql

These two queries in SparkSQL return the same value and I don't know why.
Treating the condition attribute as integer or string.
select count(*) from <my_table> where <my_column> = 100
union all
select count(*) from <my_table> where <my_column> = '100'

In Logical plan it cast string values to int values based on schema refer this to understand more - https://medium.com/datalex/sparks-logical-and-physical-plans-when-why-how-and-beyond-8cd1947b605a
where column = 0 ............................................and where column = '0'

Related

return the column name from dynamic string

I want to get the column from the dynamic string, In my table: MyTable2 I have many columns/fields, which are :
MyVarCharColumnName1,MyVarCharColumnName2,MyVarCharColumnName3,MyVarCharColumnName4
These above fields are nvarchar(50),
I wonder how I can get the value of them when join with another table as below example:
SELECT
*,
CASE
WHEN Tbl1.MyId IN ('1', '2', '3', '4')
THEN (SELECT 'MyVarCharColumnName' + bf.MyId
FROM MyTable2)
ELSE Tbl1.MyId
END AS TheNameofId
FROM
Tbl1
above is wrong because it will return MyVarCharColumnName1 as TheNameofId value instead of the value inside MyVarCharColumnName1
Is there are some sql function that can return the column name from a string?
any way to convert 'MyVarCharColumnName1' to column object?
As it is confirmed that you have to write dynamic query to do in the same way as you are asking but beside that we can do the same in the following way using CASE
SELECT
*,
CASE
WHEN Tbl1.MyId = 1 THEN MyVarCharColumnName1
WHEN Tbl1.MyId = 2 THEN MyVarCharColumnName2
WHEN Tbl1.MyId = 3 THEN MyVarCharColumnName3
WHEN Tbl1.MyId = 4 THEN MyVarCharColumnName4
ELSE Tbl1.MyId
END AS TheNameofId
FROM Tbl1

How to loop through one table and then Insert into another based on multiple IF ELSE

I have a table like below with 2 columns. This table already is populated with all the data I need.
Table 1
ID (int) TYPE (string)
The other table looks like this and it's empty
Table 2
ID (int) Somedetail (int)
I need to loop through Table 1 and then insert into Table 2 if TYPE = 'string'
for each row and I have about 5 different string I need to test against.
INSERT WILL BE insert into Table 2 (ID, int). I will provide the int value based on if TYPE = 'string' matches or not.
This is what I have currently.
SELECT ID, TYPE
FROM TABLE1
IF(ID = 'STRING1')
INSERT INTO TABLE2...
ELSE IF (ID = 'STRING2')
INSERT INTO
and so on
You are basically looking for an INSERT INTO SELECT statement (https://learn.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql). In your case this would take the form:
INSERT INTO Table2
SELECT
id,
CASE
WHEN type = 'string1' THEN intvalue1
WHEN type = 'string2' THEN intvalue2
WHEN type = 'string3' THEN intvalue3
WHEN type = 'string4' THEN intvalue4
WHEN type = 'string5' THEN intvalue5
END
FROM Table1
WHERE type IN ('string1', 'string2', 'string3', 'string4', 'string5');
Where we just take the results of that SELECT statement and shove it into Table2 with the INSERT INTO.
Fairly positive you want to use CASE based on your comments. You'll have to fill in the strings and the ints that you want, but here is the shell:
INSERT INTO Table2 (ID, Somedetail)
SELECT ID,
CASE WHEN Type = 'string1' THEN 1,
WHEN Type = 'string2' THEN 2,
etc...
END as Somedetail
FROM Table1

If value return the value. If a record not exists or when column is null, return 0 in Sql Server - different ways

I want to return 0 if there is no record or if the Column1 is null.
select #var = Column1
from myschema.mytable
where Id = #suppliedId;
select isnull(#var, 0);
The above code outputs 0 if if Column1 is null. Or if a row is not found
Whereas I tried to save some keystrokes but it resulted in,
select isnull(Column1, 0)
from myschema.mytable
where Id = #suppliedId;
The above code outputs null if Column1 is null or when there is no row
Any ideas what is wrong here ? Or is there any shorter way of writing the first code ?
You can do
SELECT #var = ISNULL(MAX(Column1), 0)
FROM myschema.mytable
WHERE Id = #suppliedId;
A scalar aggregate always returns a single row even if the underlying query returns zero rows.
Not really saving key strokes, but something like this could help :-)
SELECT TOP 1 tbl.field
FROM
(
SELECT 0 AS inx, 'no record' AS field
--if only one row is possible, than set '1' literally
UNION SELECT ROW_NUMBER() OVER(ORDER BY mytable.orderfield), ISNULL(mytable.Land,'is null')
FROM mytable
WHERE IDENTITY = #suppliedID
) AS tbl
ORDER BY tbl.inx DESC

Set of values such that no rows match condition

I have a table with column uuid and type. I want all the uuid's 'xxxxx' such that no rows have uuid = 'xxxxx' AND type = 'buy'.
This ends up the same as if you took all uuid's in the table, and then removed all uuid's that match SELECT uuid FROM table WHERE type = 'buy'.
I approach these problems using aggregation and a having clause:
select a_uuid
from table t
group by a_uuid
having sum(case when type = 'Purchase' then 1 else 0 end) = 0;
EDIT:
If you have a table with one row per a_uuid, then the fastest is likely to be:
select a_uuid
from adtbs a
where not exists (select 1 from table t where t.a_uuid = a.a_uuid and t.type = 'Purchase');
For this query, you want an index on table(a_uuid, type).
select a_uuid
from t
group by a_uuid
having not bool_or(type = 'Purchase')
http://www.postgresql.org/docs/current/static/functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE

Return zero if no record is found

I have a query inside a stored procedure that sums some values inside a table:
SELECT SUM(columnA) FROM my_table WHERE columnB = 1 INTO res;
After this select I subtract res value with an integer retrieved by another query and return the result. If WHERE clause is verified, all works fine. But if it's not, all my function returns is an empty column (maybe because I try to subtract a integer with an empty value).
How can I make my query return zero if the WHERE clause is not satisfied?
You could:
SELECT COALESCE(SUM(columnA), 0) FROM my_table WHERE columnB = 1
INTO res;
This happens to work, because your query has an aggregate function and consequently always returns a row, even if nothing is found in the underlying table.
Plain queries without aggregate would return no row in such a case. COALESCE would never be called and couldn't save you. While dealing with a single column we can wrap the whole query instead:
SELECT COALESCE( (SELECT columnA FROM my_table WHERE ID = 1), 0)
INTO res;
Works for your original query as well:
SELECT COALESCE( (SELECT SUM(columnA) FROM my_table WHERE columnB = 1), 0)
INTO res;
More about COALESCE() in the manual.
More about aggregate functions in the manual.
More alternatives in this later post:
How to return a value from a function if no value is found
I'm not familiar with postgresql, but in SQL Server or Oracle, using a subquery would work like below (in Oracle, the SELECT 0 would be SELECT 0 FROM DUAL)
SELECT SUM(sub.value)
FROM
(
SELECT SUM(columnA) as value FROM my_table
WHERE columnB = 1
UNION
SELECT 0 as value
) sub
Maybe this would work for postgresql too?
You can also try: (I tried this and it worked for me)
SELECT ISNULL((SELECT SUM(columnA) FROM my_table WHERE columnB = 1),0)) INTO res;
You can use exists clause.
IF EXISTS(SELECT FROM my_table WHERE columnB = 1)
THEN
res := SUM(columnA);
ELSE
res := 0
END IF;