How to get the header out of Select query execution in snowflake - sql

How to get header name from select query execution in snowflake. Currently I am getting only values out of select query execution. is there way to get column name as well. I need to group by and aggregate function on top of the select query result.
Code tried
sql10 = f"""SELECT col1,col2,col3,col4 FROM tablename ORDER BY col4 ;"""
select_snow =cs.execute(sql10).fetchall()
snow_col = [(c[1],c[2]) for c in select_snow]
how to get the columns name and mapped to particular column value.
Output
select snow: [('value1','value12','value3','value4'), ('value1','value12','value3','value4'), ('value11','value12','value13','value14'), ('value21','value22','value23','value24')]

Related

t-sql query returns undefined after using ORDER BY

I am currently working with a MS SQL database on Windows 2012 Server
I need to query only 1 column from a table that I only have access to read, not make any kind of changes.
Problem is that the name of the column is "Value"
My code is this:
SELECT 'Value' FROM table
If I add
`ORDER BY 'Value'`
The issue is that the query is returning an empty list of results.
Things I've tried already
I tried replacing ' with `"' but this didn't work either.
I also tried writing SELECT * instead of SELECT VALUE
Using the table name in the SELECT or ORDER clauses again didn't help
You are claiming that this query:
SELECT 'Value'
FROM table
ORDER BY 'Value'
Is returning no rows. That's not quite correct. It is returning an error because SQL Server does not allow constant expressions as keys for ORDER BY (or GROUP BY for that matter).
Do not use single quotes. In this case:
SELECT 'Value' as val
FROM table
ORDER BY val;
Or, if value is a column in the table:
SELECT t.Value
FROM table t
ORDER BY t.Value;
Value is not a reserved word in SQL Server, but if it were, you could escape it:
SELECT t.[Value]
FROM table t
ORDER BY t.[Value];
it looks like your table has null values. and because of the order by all null values come first.
try to add filter like this
select Value FROM table
where Value is not null and Value <> ''
order by Value

Subquery with GROUPBY on calculated field: Your query does not include the specified expression '' as part of an aggregate function

I get the following error message
"Your query does not include the specified expression 'SampleCode' as part of an aggregate function."
I've looked into aggregate functions and have tried various ways to GROUP BY using the individual data fields that make up the code but I can't seem to get anything to work.
'SampleCode' is a concatenated query field (query name: datqry_SampleNumber) that is based on data from 3 different tables to create a unique value as follows...
SampleCode: IIf([tbl_Carcass.SampleNumber]="-999","-999",
"NPT-" & [tbl_SurveyInfo.SurveyYear*] & "-" &
[datqry_TransectData.Project_Code] & "-" & [tbl_Carcass.SampleNumber])
for SampleNumber values > 0001 (-999 is a placeholder indicating no SampleNumber assigned). Note, SurveyYear* is a calculated field based on the SurveyDate data field.
So, since SampleCode needs to be unique to each sample, I am trying to build a duplicate query, based on the aforementioned query, to identify duplicate SampleCodes so they can be relabeled and archived w/ a unique qualifier. The criteria for the duplicate query operation is as follows
In (SELECT [SampleCode] FROM [datqry_SampleNumber] As Tmp
GROUP BY [SampleCode] HAVING Count(*)>1 )
Any ideas on how to tackle this problem? Thank you in advance for your help and suggestions.
This looks like it might be a limitation of the JET engine used by Access to interpret its SQL.
It appears to be having trouble working with the subquery because it contains an aggregation of a calculated field (SampleCode in your case).
Try saving this as a separate query called, e.g. qryDuplicates:
SELECT [SampleCode] FROM [datqry_SampleNumber]
GROUP BY [SampleCode] HAVING Count(*)>1;
Then what you are trying to do will work as expected:
SELECT * from someTable WHERE someField IN (
SELECT * FROM qryDuplicates
);
TECHNICAL NOTE: I've tested it out and it is indeed specific to the fact that SampleCode is a calculated field. Doing exactly the same kind of grouped subquery works as expected when the field in question is not calculated.
With this test database this query works:
SELECT * FROM Table2 WHERE Field3 IN (
SELECT Field1 FROM datqry_SampleNumber
GROUP BY Field1 HAVING COUNT(*) > 1
);
And this doesn't
SELECT * FROM Table2 WHERE Field3 IN (
SELECT SampleCode FROM datqry_SampleNumber
GROUP BY SampleCode HAVING COUNT(*) > 1
);

sql server - how to execute the second half of 'or' clause only when first one fails

Suppose I have a table with following records
value text
company/about about Us
company company
company/contactus company contact
I have a very simple query in sql server as below. I am having problem with the 'or' condition. In below query, I am trying to find text for value 'company/about'. If it is not found, then only I want to run the other side of 'or'. The below query returns two records as below
value text
company/about about Us
company company
Query
select
*
from
tbl
where
value='company/about' or
value=substring('company/about',0,charindex('/','company/about'))
How can I modify the query so the result set looks like
value text
company/about about Us
A bit roundabout, but you can check for the existence of results from the first where clause:
select
*
from
tbl
where
value='company/about' or
(
not exists (select * from tbl where value='company/about')
and
value=substring('company/about',0,charindex('/','company/about'))
)
Since your second condition can be re-written as value = 'company' this would work (at least for the data and query you've presented):
select top(1) [value], [text]
from dbo.MyTable
where value in ('company/about', 'company')
order by len(value) desc
The TOP() ignores the second row if both are found, and the ORDER BY ensures that the first row is always the one with 'company/about', if it exists.

How do I select only 1 row in sybase without using rowcount

How do I select only 1 row in sybase without using rowcount? I don't have the privilege to set rowcount in sybase. Is there a way to select only 1 row?
For example:
select * from table where name = 'jack'
This returns two rows; how do I select only one row from the result set without using set rowcount?
Try the query:
SELECT TOP 1 * FROM mytable
WHERE name = 'jack'
As you might guess, this selects the TOP 1 matching results. If you wanted more (which you don't here) you could use any number (TOP 100 or TOP 1000, etc).
A more comprehensive example can be found on w3schools: http://www.w3schools.com/Sql/sql_top.asp
There seems to be a reason, why you're getting more than 1 row for "WHERE name = 'jack'", it looks as if the rows differ.
But if, the rows do not differ you can try adding "distinct":
SELECT DISTINCT * FROM TABLE WHERE name = 'jack'
or try with "GROUP BY" statement, then you should type explicitly all columns, eg.:
SELECT name FROM TABLE WHERE name = 'jack' GROUP BY name
if this is not what you wanted, can you paste here how the 2 rows look exactly?
If you want a single result, use 'GROUP BY' and 'HAVING column = max(column)'. Or replace max() with min().
This should work unless the max or min values are also not unique.

Use of CASE statement values in THEN expression

I am attempting to use a case statement but keep getting errors. Here's the statement:
select TABLE1.acct,
CASE
WHEN TABLE1.acct_id in (select acct_id
from TABLE2
group by acct_id
having count(*) = 1 ) THEN
(select name
from TABLE3
where TABLE1.acct_id = TABLE3.acct_id)
ELSE 'All Others'
END as Name
from TABLE1
When I replace the TABLE1.acct_id in the THEN expression with a literal value, the query works. When I try to use TABLE1.acct_id from the WHEN part of the query, I get a error saying the result is more than one row. It seems like the THEN expression is ignoring the single value that the WHEN statement was using. No idea, maybe this isn't even a valid use of the CASE statement.
I am trying to see names for accounts that have one entry in TABLE2.
Any ideas would be appreciated, I'm kind of new at SQL.
First, you are missing a comma after TABLE1.acct. Second, you have aliased TABLE1 as acct, so you should use that.
Select acct.acct
, Case
When acct.acct_id in ( Select acct_id
From TABLE2
Group By acct_id
Having Count(*) = 1 )
Then ( Select name
From TABLE3
Where acct.acct_id = TABLE3.acct_id
Fetch First 1 Rows Only)
Else 'All Others'
End as Name
From TABLE1 As acct
As others have said, you should adjust your THEN clause to ensure that only one value is returned. You can do that by add Fetch First 1 Rows Only to your subquery.
Then ( Select name
From TABLE3
Where acct.acct_id = TABLE3.acct_id
Fetch First 1 Rows Only)
Fetch is not accepting in CASE statement - "Keyword FETCH not expected. Valid tokens: ) UNION EXCEPT. "
select name from TABLE3 where TABLE1.acct_id = TABLE3.acct_id
will give you all the names in Table3, which have a accompanying row in Table 1. The row selected from Table2 in the previous line doesn't enter into it.
Must be getting more than one value.
You can replace the body with...
(select count(name) from TABLE3 where TABLE1.acct_id = TABLE3.acct_id)
... to narrow down which rows are returning multiples.
It may be the case that you just need a DISTINCT or a TOP 1 to reduce your result set.
Good luck!
I think that what is happening here is that your case must return a single value because it will be the value for the "name" column. The subquery (select acct_id from TABLE2 group by acct_id having count(*) = 1 ) is OK because it will only ever return one value. (select name from TABLE3 where TABLE1.acct_id= TABLE3.acct_id) could return multiple values depending on your data. The problem is you trying to shove multiple values into a single field for a single row.
The next thing to do would be to find out what data causes multiple rows to be returned by (select name from TABLE3 where TABLE1.acct_id= TABLE3.acct_id), and see if you can further limit this query to only return one row. If need be, you could even try something like ...AND ROWNUM = 1 (for Oracle - other DBs have similar ways of limiting rows returned).