I have a table with two columns hora_entrada and hora_saida and when running this select statement:
select hora_entrada, hora_saida
from Controlo_de_Entrada_saidas
it shows this result:
What I want to do is to combine these two columns into one that if Hora_saida = "Não saiu", it shows the data in hora_entrada but if hora_saída has an actual hour in there, it shows the data in hora_saida instead.
So basically this should be my result:
I don't know if I'm making myself clear, I actually don't even know where to start or if its even possible but any help would be appreciated.
Try using a CASE expression:
SELECT
hora_entrada,
hora_saida,
CASE WHEN hora_saida = 'Não saiu'
THEN hora_entrada ELSE hora_saida END AS new_column
FROM yourTable;
This logic assumes that any value in the hora_saida column which is not Não saiu is a valid timestamp. If not, then we could add additional logic to check for this as well.
If you are open/able to changing your data model, you might want to consider just storing NULL values for the missing data. SQL Server (and most other databases as well) has a built-in function COALESCE, which can be used to replace NULL with a backup value. This would avoid needing to use a lengthy CASE expression as you see above.
Related
I have a handful of scalar-valued functions (which I appreciate may not be best practice, but for now, this will suffice, this is simply a development exercise) which I use within various computed columns with MS SQL tables.
I have a scenario whereby I need to use the result of one of these functions, as a parameter to another within a given computed column. For example;
(case when [DynamicQuantity] IS NULL then ([dbo].[GetFiatValue]([Currency],[Quantity])) ELSE ([dbo].[GetFiatValue]([Currency],([dbo].[getStakedQuantity]([currency])))) end)
If the given [DynamicQuantity] field is null (a column value generated by another SVF), use the [Quantity] field. However, if [DynamicQuantity] is populated, the ELSE will fire, and pass the output of the [dbo].[getStakedQuantity] SVF in place of the [Quantity] value.
Is this achievable? I can't seem to get the syntax to work and am questioning whether this is even possible?
Running it via a normal query works;
SELECT case when [DynamicQuantity] IS NULL then [dbo].[GetFiatValue]([Currency],[Quantity]) ELSE [dbo].[GetFiatValue]([Currency],[dbo].[getStakedQuantity]([currency])) end from dbo.cryptoPortfolio
But when used as a computed column formula below;
case when [DynamicQuantity] IS NULL then [dbo].[GetFiatValue]([Currency],[Quantity]) ELSE [dbo].[GetFiatValue]([Currency],[dbo].[getStakedQuantity]([currency])) end
SSMS will not accept it, with Error validating the formula for column 'FiatValue'.
I have 2 data sets that have the common column VNO. Now I want to get the report in ssrs like
VDate, Count('') from B for Vdate, Count('') from A for Vdate
Can anyone help me with the way, I tried the lookup but not able to get this output.
Note: I cannot join these two tables in SQL as these 2 tables are on separate instances and they are not connected and don't have permission to do so.
You need to use LOOKUPSET() . This returns an array which you can then check the length of like this
=LookupSet(Fields!InvoiceDate.Value, Fields!VDate.Value, Fields!VNO.Value, "DataSetB").Length
The 3rd argument is the returned value but as you are only getting a count, it does not matter what we return there. DataSetB is the case sensitive name of your second dataset.
(Opening the following on behalf of a Snowflake client...)
When I try to insert into the table it threw below error:
Numeric value 'abc_0011O00001y31VpQAI' is not recognized
Have check the table DDL and found only 3 columns defined as NUMBER and rest as VARCHAR.
I checked the SELECT query and didnot find any string value in those NUMBER Datatype columns. Also tried searching in all the Varchar columns for the value 'abc_0011O00001y31VpQAI' , I didn't find any
I know one thing Snowflake doesn't always shows correct error. Am I missing anything here? Is there any way to fix it?
Both COL4_MRR and COL5_QUANTITY are NUMBER
INSERT INTO TABLE
(COL1_DATE, COL2_CD, COL3_CUST_NAME, COL3_LOC_NAME,COL4_MRR,COL5_QUANTITY)
SELECT
'2019-10-03' AS COL1_DATE ,
'AE' AS COL2_CD
,CUSTOMER_NAME AS COL3_CUST_NAME
,LOCATION_NAME AS COL3_LOC_NAME
,MRR_BILLED as COL4_MRR
,QTY_BILLED as COL5_QUANTITY
FROM SCHEMA.V_TABLEA
union all
SELECT
'2019-10-03' AS COL1_DATE ,
'BE' AS COL2_CD
,CUSTOMER_NAME AS COL3_CUST_NAME
,LOCATION_NAME AS COL3_LOC_NAME
,NULL as COL4_MRR
,QTY_BILLED as COL5_QUANTITY
FROM SCHEMA.V_TABLEB
I created a table_D same as original TABLE and tried inserting into it , it worked fine . Then Inserted into Original TABLE from table_D , it worked again .
Deleted those rows from original TABLE and reran the job , it worked fine.
There was no issue with data as all was Number only, I even tried with TRY_TO_NUMBER too. It inserted the data without any changes to the code.
...............
Client is currently waiting on a next day run to re-test to determine if this is either a bug or an issue with their data. In the meantime, we are interested to see if anyone else has run into similar challenges and have a viable recommendation. THANK YOU.
The error typically means you are trying to insert non-numeric data (like 'abc_0011O00001y31VpQAI') into a numeric column. It seems like the customer did everything right in testing and TRY_TO_NUMBER() is a great way to verify numeric data.
Do the SELECT queries run fine separately? If so, then I would check whether there might be a potential mismatch in the datatype of the columns and make sure they are in the right order.
I would also check whether or not the header is being skipped in the file (that may be where the 'abc_0011O00001y31VpQAI' is coming from since the customer did not see it in the data).
SELECT queries work fine, I tried creating a new table with same DDL as original and tried loading into that new table, it worked fine. Not sure why it is not loading into the original table
For those of you who have actually delt with RETS may be able to give me a hand here. The problem occurs when multiple properties are tied into the RETS data even though the property is sold. Basically what I need is to be able to check the database with the SELECT statement against three fields. The fields in question would be C_StreetName, C_StreetNumber, and C_PostalCode.
To make this clear what I want is some type of way to check for duplicates while gathering the dataset, this can't be done in php because of how the data is returned through the application. So if it finds another record with the same C_StreetName, C_StreetNumber, and C_PostalCode it will remove them from the dataset. Ideally it would be nice if it could also check the Status of the two to find out if one is Expired or Sold before removing them from the data.
I'm not familiar with complex SQL functions, I was looking at the IF statement until I found that can only be used while storing data not the other way around. And the CASE statement but it just doesn't seem like that would work.
If you guys have any suggestions on what I should use I'd appreciate it. Hopefully there is a way to do this and keep in mind this is only one table I am accessing I don't have any Joins.
Thanks in advance.
Here's something to get you going in the right direction. I haven't tested this, and am not sure you can nest a case expression inside max() in mysql.
What this accomplishes is to output one row per unique combination of street name, number and postcode, with a status of 'Expired' or 'Sold' taking precedence over other values. That is, if there's a row with 'Expired' it will be output in preference to non-expired and non-sold, and a row with 'Sold' will be output if it exists, regardless of what other rows exist for that property. The case statement just converts the status codes into something orderable.
select
C_StreetName,
C_StreetNumber,
C_PostalCode,
max(
case status
when 'Expired' then 1
when 'Sold' then 2
else 0
end) as status
group by
C_StreetName,
C_StreetNumber,
C_PostalCode;
I've been battling this one for a while now. I have a stored proc that takes in 3 parameters that are used to filter. If a specific value is passed in, I want to filter on that. If -1 is passed in, give me all.
I've tried it the following two ways:
First way:
SELECT field1, field2...etc
FROM my_view
WHERE
parm1 = CASE WHEN #PARM1= -1 THEN parm1 ELSE #PARM1 END
AND parm2 = CASE WHEN #PARM2 = -1 THEN parm2 ELSE #PARM2 END
AND parm3 = CASE WHEN #PARM3 = -1 THEN parm3 ELSE #PARM3 END
Second Way:
SELECT field1, field2...etc
FROM my_view
WHERE
(#PARM1 = -1 OR parm1 = #PARM1)
AND (#PARM2 = -1 OR parm2 = #PARM2)
AND (#PARM3 = -1 OR parm3 = #PARM3)
I read somewhere that the second way will short circuit and never eval the second part if true. My DBA said it forces a table scan. I have not verified this, but it seems to run slower on some cases.
The main table that this view selects from has somewhere around 1.5 million records, and the view proceeds to join on about 15 other tables to gather a bunch of other information.
Both of these methods are slow...taking me from instant to anywhere from 2-40 seconds, which in my situation is completely unacceptable.
Is there a better way that doesn't involve breaking it down into each separate case of specific vs -1 ?
Any help is appreciated. Thanks.
I read somewhere that the second way will short circuit and never eval the second part if true. My DBA said it forces a table scan.
You read wrong; it will not short circuit. Your DBA is right; it will not play well with the query optimizer and likely force a table scan.
The first option is about as good as it gets. Your options to improve things are dynamic sql or a long stored procedure with every possible combination of filter columns so you get independent query plans. You might also try using the "WITH RECOMPILE" option, but I don't think it will help you.
if you are running SQL Server 2005 or above you can use IFs to make multiple version of the query with the proper WHERE so an index can be used. Each query plan will be placed in the query cache.
also, here is a very comprehensive article on this topic:
Dynamic Search Conditions in T-SQL by Erland Sommarskog
it covers all the issues and methods of trying to write queries with multiple optional search conditions
here is the table of contents:
Introduction
The Case Study: Searching Orders
The Northgale Database
Dynamic SQL
Introduction
Using sp_executesql
Using the CLR
Using EXEC()
When Caching Is Not Really What You Want
Static SQL
Introduction
x = #x OR #x IS NULL
Using IF statements
Umachandar's Bag of Tricks
Using Temp Tables
x = #x AND #x IS NOT NULL
Handling Complex Conditions
Hybrid Solutions – Using both Static and Dynamic SQL
Using Views
Using Inline Table Functions
Conclusion
Feedback and Acknowledgements
Revision History
If you pass in a null value when you want everything, then you can write your where clause as
Where colName = IsNull(#Paramater, ColName)
This is basically same as your first method... it will work as long as the column itself is not nullable... Null values IN the column will mess it up slightly.
The only approach to speed it up is to add an index on the column being filtered on in the Where clause. Is there one already? If not, that will result in a dramatic improvement.
No other way I can think of then doing:
WHERE
(MyCase IS NULL OR MyCase = #MyCaseParameter)
AND ....
The second one is more simpler and readable to ther developers if you ask me.
SQL 2008 and later make some improvements to optimization for things like (MyCase IS NULL OR MyCase = #MyCaseParameter) AND ....
If you can upgrade, and if you add an OPTION (RECOMPILE) to get decent perf for all possible param combinations (this is a situation where there is no single plan that is good for all possible param combinations), you may find that this performs well.
http://blogs.msdn.com/b/bartd/archive/2009/05/03/sometimes-the-simplest-solution-isn-t-the-best-solution-the-all-in-one-search-query.aspx