The documentation for the VBA Select Case statement doesn't seem to address this question expressly, but are the Case clauses executed in order or should the code intended to be run second be placed in a separate conditional structure?
I.e., If Oranges must run after Apples, is it better to do:
Select Case My.Property
Case "Foo"
Apples
Case "Bar"
Oranges
End Select
Or should it be:
Select Case My.Property
Case "Foo"
Apples
End Select
Select Case My.Property
Case "Bar"
Oranges
End Select
Thanks for any constructive input and apologies if this is a stupid question.
Related
HELP! Kind of new to SQL. I've been working with simple statements for a few years but I need a little advanced help. I know it can be done and will save me time.
Here is my example to try to find results:
select top 1 apples, color from fruits
where apples in ('gala', 'fuji', 'granny')
and (inStock is not null and inStock <> '')
In the above query I would get the first color in 'gala' apples and thats it. What I want is the first color in 'gala', the first in 'fuji', first in 'granny' and so on.
InStock isn't as important - it's just an additional filter in the search results.
What I want is a two column list. Left Column being apple types and right column being the first color result for each apple type.
You can use row_number() window ranking function to serialize apples wise colors in a specific order. Then choose first one from each group by selecting first rows.
with cte as
(
select apples, color ,row_number()over(partition by apples order by apples) rn from fruits
where apples in ('gala', 'fuji', 'granny')
and (inStock is not null and inStock <> '')
)
select apples, color from cte where rn=1
I think one issue you might have here is the concept of "first". A color is a categorical variable and tables don't typically attach meaning to a "first" or "last" value with a few exceptions. If you're dead set on returning the first row for each fruit, one easy way to get the result utilizes union all.
SELECT top 1 apples, color from fruits where apples = 'gala'
UNION ALL
SELECT top 1 apples, color from fruits where apples = 'fuji'
UNION ALL
SELECT top 1 apples, color from fruits where apples = 'granny'
I'm finding that when I try to select a column in a SQL case statement, it doesn't work unless I wrap it in a numeric function. The max(price) seems to select the value in the column, while just price, or price always returns blank.
I think its a bug.
This doesn't work:
SELECT
auction,
CASE WHEN auction='1'
THEN (select max(bid.amount) from bid where bid.auction_id = auction.id)
ELSE price
END as price_string
FROM product
This works:
SELECT
auction,
CASE WHEN auction='1'
THEN (select max(bid.amount) from bid where bid.auction_id = auction.id)
ELSE max(price)
END as price_string
FROM product
Edit: fixed comma.
This is not a bug.
In the query that doesn't work, the two halves of your CASE statement are incompatible. You have an aggregate function (MAX(bid.amount)) that returns a single value for one part of your CASE statement, and the name of a column, which will return a set, for the other part of your CASE statement. You cannot mix aggregates and sets like this.
The query that works does so because both halves of the CASE statement are returning aggregate values and are therefore compatible.
Take a simple table:
test_table
col1 | col2
1 7
5 14
8 3
3 9
If I query like this:
SELECT col1 FROM test_table
I'll get this result, a set:
col1
1
5
8
3
But if I query like this:
SELECT MAX(col1) FROM test_table
I'll get a single value:
8
I have a select statement that obviously pulls some results from my database. Once I get those results, I would like to access them one at a time for another Select statement, is that possible? I am doing this in a user defined function.
Example:
SELECT differentKindsOfBread FROM breadDrawer
WHERE differentKindsOfBread IS NOT Null
Now I want to use my results to do another Select like:
SELECT differentKindsOfBread[1] FROM differentKindsOfBread
WHERE blah = blahblah
EDIT
Lets say differentKindsOfBread selected:
Rye
White
Wheat
half-Wheat
Now I want to do selects for each one like:
Select Rye (differntKindsOfBread[0]) ...
Select White (differntKindsOfBread[1]) ...
Thanks,
I have a table similar to the following:
Date Description Value1 Value2
01/01/2012 shiny colour 2 0
01/01/2012 yellow colour 2 2
03/01/2012 matt colour 2 2
03/01/2012 matt 4 1
03/01/2012 shiny 2 2
I want to write a SELECT SQL query (T-SQL) that will output all of the above columns but also display an extra column as the output of the SELECT statement whose value depends on the presence of the word "colour" in the Description (if "colour" is present it would be one value, if not it would show a different value).
(I would also want to display another extra column on top of that whose value depends on the presence of the words "matt" or "shiny" in the Description column. But I assume the method of doing this would be similar).
I believe I should be able to do this using the COALESCE function but I'm not familiar with this and am struggling to get anything working?
EXTENSION
Hey, thanks for your answers. They're really helpful. I have one more extension to the question. My second generated column relies on info in the first generated column. So something like:
SELECT *,
CASE
WHEN Description LIKE '%colour%' THEN 'SomeValue'
ELSE 'Unclassified'
END AS Category1,
CASE
WHEN AnotherColumn LIKE 'Something' THEN 'SomeValue'
WHEN Category1='Unclassified' THEN 'Unclassified'
ELSE 'Generic'
END AS Category2
FROM table_name
How do I get the output of Category2 to rely on output of Category1? I'm trying something like the above but it's not working.
My extension question was answered here: T-SQL CASE statement relies on another CASE statement in same SELECT query
SELECT *,
CASE WHEN Description LIKE '%colour%' THEN
1
ELSE
0
END AS HasColour,
CASE WHEN Description LIKE '%matt%' THEN
1
ELSE
0
END AS HasMatt,
CASE WHEN Description LIKE '%shiny%' THEN
1
ELSE
0
END AS HasShiny
FROM table_name
You would just add more columns for all the different words that you want to search for. Obviously you can change the return type of the columns to whatever you want, but I thought a boolean would be suitable in this situation.
Unless I misunderstand what you are asking, you could use a case statement:
SELECT Date,
Description,
Value1,
Value2,
Case when Description like '%colour%' then OTHERCOL else OTHERCOL2 end as Colourful,
Case when Description like '%matt%' then OTHERCOL else OTHERCOL2 end as Matt,
Case when Description like '%shiny%' then OTHERCOL else OTHERCOL2 end as Shiny,
FROM yourTable
Is there any way to make this query run faster (meaning take less reads/IO from SQL Server). The logic essentially is
I count distinct values from a column
if there is any more than 1 distinct value, it is considered as existing
List is built with the name of the column and a 1 or 0 if it is existing
I would like to do something with EXISTS (in t-sql that terminates the scan of the table/index if SQL Server finds the match to the EXISTS predicate). I am not sure if that is possible in this query.
Note: I am not looking for answers like is there an index on the table...well beyond that :)
with SomeCTE as
(
select
count(distinct(ColumnA)) as ColumnA,
count(distinct(ColumnB)) as ColumnB,
count(distinct(ColumnC)) as ColumnC
from VERYLARGETABLE
)
select 'NameOfColumnA', case when ColumnA > 1 then 1 else 0 end from SomeCTE
UNION ALL
select 'NameOfColumnB', case when ColumnB > 1 then 1 else 0 end from SomeCTE
UNION ALL
select 'NameOfColumnC', case when ColumnC > 1 then 1 else 0 end from SomeCTE
Just to copy what I posted below in the comments.
So after testing this solution. It makes the queries run "faster". To give two examples..one query went from 50 seconds to 3 seconds. Another went from 9+ minutes (stopped running it) went down to 1min03seconds. Also I am missing indexes (so according to DTA should run 14% faster) also I am running this in the SQL Azure DB (where you are being throttled drastically in terms of I/O, CPU and tempddb memory)...very nice solution all around. One downside is that min/max does not work on bit columns, but those can be converted.
If the datatype of the columns allow aggregate functions and if there are indexes, one for every column, this will be fast:
SELECT 'NameOfColumnA' AS ColumnName,
CASE WHEN MIN(ColumnA) < MAX(ColumnA)
THEN 1 ELSE 0
END AS result
FROM VERYLARGETABLE
UNION ALL
SELECT 'NameOfColumnB',
CASE WHEN MIN(ColumnB) < MAX(ColumnB)
THEN 1 ELSE 0
END
FROM VERYLARGETABLE
UNION ALL
SELECT 'NameOfColumnC'
CASE WHEN MIN(ColumnC) < MAX(ColumnC)
THEN 1 ELSE 0
END
FROM VERYLARGETABLE ;