How to select column value depends on its existence? - sql-server-2008

I need to write query that should return one column depends on existence of value in 2 columns in this way:
The columns are: C1 and C2 and they are in the same table T. If C1 exists then return C1, if C1 doesn't exist return C2.

select case when isnull(C1,'')<>'' then C1
else C2
end as Column_name
from table T
Case statement is used here.

select case when isnull(C1,'')<>'' then C1
when isnull(C2,'')<>'' then C2
end as Column_name
from table T

Related

Why does SQL NOT EXISTS return 1 record of all NULL values

SQL Fiddle on the following:
create table tbl( col1 int, col2 int, col3 int);
insert into tbl values(1,1,1);
insert into tbl values(1,1,1);
select sum(col1) c1, sum(col2) c2, sum(col3)c3
from tbl
where not exists (
select 2 as c1, 2 as c2, 2 as c3
)
I am expecting this to return 0 records. Instead it returns 1 record of null values. Can you tell me why?
P.s. I am trying to understand not exists behavior.
It's not about the EXISTS. Your NOT EXISTS evaluates to FALSE, since SELECT 2 AS c1, 2 AS c2, 2 AS c3 always returns a row. This means your query is equivalent to:
SELECT SUM(col1) c1, SUM(col2) c2, SUM(col3) c3 FROM tbl WHERE 0
Saying that, this is actually about the SUM semantics. SUM even in a empty set should return a value, and the value in this case is NULL.
From mysql documentation:
SUM(expr)
Returns the sum of expr. If the return set has no rows, SUM() returns NULL.
SUM() returns NULL if there were no matching rows.
In addition to what JuniorCompressor pointed, it's important to note the order of execution of SQL clauses within a query. WHERE runs first, then the SELECT list, where aggregates are being calculated on an empty result set, whose result in null, as they got nothing to process.
To actually discard that result as you expect, you would need a HAVING clause, which runs afterwards, and it can filter out based on the results of aggregates.
The difference is subtle, but makes the whole point of this question. WHERE decides which raw rows qualify to integrate an aggregate. HAVING decides which aggregate result to include in the final result.

MySQL INSERT INTO Mytable VALUES(NULL) WHERE VALUES ('NA');

I have in Mytable some value = 'NA'
Insted of this value I would like to put NULL.
So I've write:
INSERT INTO Mytable
VALUES(NULL)
WHERE VALUES('NA');
But I didn't work.
I didn't put the name of the column because potentially all column can have some 'NA' value.
I hope someone have a idea to do it.
Regards
Sam
UPDATE Mytable
SET value = NULL
WHERE value = 'NA';
Yes, you must do this for each column/attribute that you want to update.
UPDATE Mytable SET value = NULL WHERE value = 'NA'
To replace occurrences of 'NA' with NULL in multiple columns, for all rows in a table, you can do this in a single update query. The trick is to assign the current value of the column back to the column when you don't want the value changed.
For example:
UPDATE Mytable t
SET t.column_one = IF(t.column_one='NA',NULL,t.column_one)
, t.column_two = IF(t.column_two='NA',NULL,t.column_two)
, t.column_fee = IF(t.column_fee='NA',NULL,t.column_fee)
WHERE t.column_one = 'NA'
OR t.column_two = 'NA'
OR t.column_fee = 'NA'
NOTES:
Repeat the column assignment for each column you need to do the replacement. (The example above references three columns, named column_one, column_two and column_fee. I don't know the names of the columns in your table; you would need to replace those references with the actual names of the columns in your table.)
The WHERE clause is optional; the query would have the same net result without that WHERE clause. (Without the WHERE clause, the query would update every row in the table; any rows that don't have an 'NA' in one of the three columns would not be changed, since the columns will all be assigned their current values.
For a lot of columns, it's more efficient to do it in a single operation, to apply several changes to a row in one statement, rather than separate statements each making updates to the same row.)
The expresssion IF(a,b,c) evaluates expression a as a boolean; if it returns TRUE, it returns expression b, otherwise it returns expression c.
To see how this works, you can run a SELECT statement (remove the SET clause, and replace the UPDATE keyword with SELECT and relevant expressions in the SELECT list:
For example:
SELECT t.column_one AS _one_old
, IF(t.column_one='NA',NULL,t.column_one) AS _one_new
, t.column_two AS _two_old
, IF(t.column_two='NA',NULL,t.column_two) AS _two_new
, t.column_fee AS _fee_old
, IF(t.column_fee='NA',NULL,t.column_fee) AS _fee_new
FROM Mytable t
WHERE t.column_one = 'NA'
OR t.column_two = 'NA'
OR t.column_fee = 'NA'
The _old columns return the existing values in the columns; the _new columns return the value that would be assigned (by the UPDATE statement earlier in my answer.)
The results from that query will verify that IF() expressions will return a NULL when the existing value in the column is 'NA'; it will also confirm that the IF() expression will return the existing value when the existing value in the column is not 'NA'.
FOLLOWUP
With 20 different tables with 12 columns each, I'd make use of the information_schema.columns table in MySQL to help me generate the required expressions.
Something like this:
SELECT CONCAT(' , t.'
,c.column_name,' = IF(t.'
,c.column_name,'=''NA'',NULL,t.'
,c.column_name,')') AS expr
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase' -- the name of your database
AND c.table_name = 'mytable' -- the name of your table
AND c.data_type IN ('varchar','char') -- only character type columns
ORDER BY c.ordinal_position
Which will return something like this:
expr
-------------------------------------
, t.fee = IF(t.fee='NA',NULL,t.fee)
, t.fi = IF(t.fi='NA',NULL,t.fi)
, t.fo = IF(t.fo='NA',NULL,t.fo)
, t.fum = IF(t.fum='NA',NULL,t.fum)
So, this doesn't actually update the table, it's just a convenient way to avoid typing out a bunch of SQL expressions. You can copy that result set, and use it to form a statement similar to the one I showed in my answer above. (Obviously, you would omit rows that you don't want to change, and the first comma would need to be changed to the SET keyword, and the rest of the statement would need to be wrapped around this.
Personally, I wouldn't bother with a WHERE clause, because if it's a lot of columns, the query is going to do a full scan of the table anyway.
SELECT CONCAT(' OR t.',c.column_name,' = ''NA''') AS expr
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase' -- the name of your database
AND c.table_name = 'mytable' -- the name of your table
AND c.data_type IN ('varchar','char') -- only character type columns
ORDER BY c.ordinal_position
This will return something like:
expr
----------------------
OR t.fee = 'NA'
OR t.fi = 'NA'
OR t.fo = 'NA'
OR t.fum = 'NA'
CAUTION: be careful that you don't do comparison of numeric columns to 'NA', because MySQL will evaluate 'NA' as a numeric value of zero (0) in a numeric context.

Need an SQL query to map column value to column name

I have following table structure (Table Name is Questions)
c1 c2 c3 Selection
X Y Z 2
A B C 3
Here c1,c2,c3 and Selection are column names. I want to retrieve value of c1 or c2 or c3 on the basis of value of column Selection.
Eg. If Selection value is 2 then I want corresponding value of c2 column i.e. Y.
If Selection value is 3 then it should select value of c3 column which is C here.
Please help me in forming Select Sql query here. I tried myself but was not able to find correct solution.
Thanks in advance
SELECT CASE Selection
WHEN 1 THEN c1
WHEN 2 THEN c2
ELSE c3
END val
FROM tableName
you have to use CASE's or IF's
select if(selection=2 ,b,if(selection=3,c,a)) from Table1 ;
see here for example ... link
This is very simple just run a simple query and it will return all the columns then you should use the appropriate column.
SELECT * FROM mytable WHERE selection = 'yourvalue'

selecting column names where data is not null or blank

SQL Server 2008
I have a table MyTable with columns A, B, C, D
When I select a row I want a list of only those columns with non-null/blanks. The result set would be
A
C
D
if B was null in my row.
Actually, there may be a column E someday. But I can get all possible column names from another table and need to check if MyTable has any of them and if so which ones have data for the row I selected
Thus:
select * from MyTable where ID = 6
select ColumnName from AllColumnNames
For each ColumnName in the result
if ColumnName exists in MyTable AND there is data in it where ID = 6, add ColumnName to output.
There's gotta be a way to do this in one query?
This will convert your table to XML in the CTE and then it uses XQuery to find the node names that does not have empty values. This will work if your column names does not break the rules for XML node names.
;with C(TableXML) as
(
select *
from MyTable
where ID = 6
for xml path('T'), elements xsinil, type
)
select T.X.value('local-name(.)', 'sysname') as ColumnName
from C
cross apply C.TableXML.nodes('/T/*') as T(X)
where T.X.value('.', 'nvarchar(max)') <> ''
Try here: https://data.stackexchange.com/stackoverflow/query/59187
Add this the the where clause if you want to exclude the ID column as well.
T.X.value('local-name(.)', 'sysname') <> 'ID'

Mysql SELECT and return multiple rows, but prefer one column value over another when present

So i'm looking to write a MySQL query that will return a result set that, when a particular column has a particular row value, it will return that row instead of another near duplicate row but otherwise return results like normal.
Okay, here is my table
id name value another
1 name1 value1
2 name1 value1 foo
3 name2 value2
4 name3 value3
and results should be (if foo is present):
id name value another
2 name1 value1 foo
3 name2 value2
4 name3 value3
I did find this example: MySQL get rows but prefer one column value over another but couldn't figure out how to adapt it to my needs...
I hope I'm making sense! No sleep in two days ain't good for attempts at elucidation! Also I'm very sorry if this has already been asked, i searched for a good long time but just didn't have the vocabulary to find any results...
Thanks in advance!
SELECT
a.*
FROM atable a
LEFT JOIN atable b ON a.name = b.name AND a.another = 'foo'
This will filter out rows with an empty another, for which an entry with the same name and value exists that does have another.
select *
from YourTable yt1
where not exists
(
select *
from YourTable yt2
where yt1.id <> yt2.id
and yt1.name = yt2.pname
and yt1.value = yt2.value
and yt1.another = ''
and yt2.another <> ''
)
This sounds like a situation where the mysql coalesce function would be handy.
Coalesce returns the first non-null parameter it's given. So you can use,
SELECT id, COALESCE(another, value) FROM MyTable;
this will return two columns, the id field and either the contents of the "another" column (if it is not null) or the contents of the "value" column.