SQL query to get the data as per the input - sql

Let’s say I am passing the input as input=2021-01-21,CGT for an sql query. CGT will be the common keyword in the database but the dates keep changing. I want the records which contain CGT and all the other dates except the date mentioned in the input parameter.
Don’t answer it as retrieve all the records that contain CGT and filter it out in Excel as the records for the particular date is huge in number. So I want the other dates which are less in count which can be handled.
Example query :-
select records from tablename where var_name=‘input’;

Based on your question, I assume that this is what you want.
Given:
| input |
---------------
2021-01-21,CGT
2021-01-22,CGT
2021-01-23,CGT
2021-01-25,CGT
2021-01-26,CGT
2021-01-27,CGT
2021-01-28,CGT
If you specify '2021-01-23' you expect to get:
| input |
---------------
2021-01-21,CGT
2021-01-22,CGT
2021-01-25,CGT
2021-01-26,CGT
2021-01-27,CGT
2021-01-28,CGT
You did not specify the database you are using. However, the concept should be similar regardless of the database platform.
SELECT *
FROM sample
WHERE SUBSTRING_INDEX(input,',',1) <> '2021-01-22'
[MySQL]
In [DB2], Given that you wish to pass in the input string and extract
the date, do the following:
SELECT *
FROM sample
WHERE SUBSTRING(input,1, (LOCATE(',',input) - 1)) <> '2021-01-22'

Related

Why I cant use the column name in the alias when i opered with dates

Currently I am migrating a database from SQL_SERVER to SPARK using HIVE_SQL.
I had an issue when im trying to pass a number to a date format.I found the answer is:
from_unixtime(unix_timestamp(cast(DATE as string) , 'dd-MM-yyyy'))
When I execute this query it bring me the data, notice that iI put an alias different to the name of column FECHA :
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(CAST(FECHA AS STRING ) ,'yyyyMMdd'), 'yyyy-MM-dd') AS FECHA_1
FROM reportes_hechos_avisos_diarios
LIMIT 1
| FECHA_1 |
| -------- |
| 2019-01-01 |
But when I put the same alias as the column name it bring me an incosistent information:
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(CAST(FECHA AS STRING ) ,'yyyyMMdd'), 'yyyy-MM-dd') AS FECHA
FROM reportes_hechos_avisos_diarios
LIMIT 1
| FECHA |
| -------- |
| 2.019 |
I know the trivial answer is , put an alias that doesnt be the same as the column name, but i have an implementation in Tableau that feeds from this query and Its complicated to change this columns because basically i must change all implementation so I need to preserve the column name.This query works for me in SQL SERVER, but i dont know why doesnt works in hive.
Issue
ExpectedResult
PSDT:Thanks for your attention, this is the first question I ask in stack and my native language is not English, sorry if I had grammatical errors.
limit 1 without order by can produce non-deterministic results from run to run because the order of rows is random due to parallel execution, some factors may affect it somehow but getting the same row is not guaranteed.
What is happening - I guess you receiving different row and the date is corrupted in that row, this is why some weird result is returned.
Also, you can another method of conversion:
select date(regexp_replace(cast(20200101 as string),'(\\d{4})(\\d{2})(\\d{2})','$1-$2-$3')) --put your column instead of constant.
Result:
2020-01-01

Concatenate /,: in a database row value after every 2 characters

I created a table in SQL Server and inserted values in that table columns in time column I stored a long string value which I retrieved from a log.
That log returns a time string like this '1103873704755', now I want to separate every 2 characters with /, (empty space) and K like this
'11/03/87 37:04:755'
Current query:
select top 1 Time
from tbl_ModBus
order by id desc
Output:
Time
-------------
1103873704755
Expected:
Time
-------------
11/03/87/ 37:04:755
So how can I get this string like I want using a SQL query?
I think that there is no a built in function to do this job in SQL.
It is always advised to use 'DATETIME ' when you are storing dates .
Yet, if you are storing data and time you better to use 'TIMESTAMP'.
Regarding all changes in the obtained value, you can do it in you programm code using whatever language you want !
I would not use a string save as DateTime.becasue it will be Unstable
If you only want to do concrete /,: in a database row value after every 2 characters.
The easiest way, you can try to use FORMAT function.
SELECT FORMAT(CAST('1103873704755' AS BIGINT),'##/##/## ##:##:###')
sqlfiddle
| |
|--------------------|
| 11/03/87 37:04:755 |

Access 2016 SQL: Find minimum absolute difference between two columns of different tables

I haven't been able to figure out exactly how to put together this SQL string. I'd really appreciate it if someone could help me out. I am using Access 2016, so please only provide answers that will work with Access. I have two queries that both have different fields except for one in common. I need to find the minimum absolute difference between the two similar columns. Then, I need to be able to pull the data from that corresponding record. For instance,
qry1.Col1 | qry1.Col2
-----------|-----------
10245.123 | Have
302044.31 | A
qry2.Col1 | qry2.Col2
----------------------
23451.321 | Great
345622.34 | Day
Find minimum absolute difference in a third query, qry3. For instance, Min(Abs(qry1!Col1 - qry2!Col1) I imagine it would produce one of these tables for each value in qry1.Col1. For the value 10245.123,
qry3.Col1
----------
13206.198
335377.217
Since 13206.198 is the minimum absolute difference, I want to pull the record corresponding to that from qry2 and associate it with the data from qry1 (I'm assuming this uses a JOIN). Resulting in a fourth query like this,
qry4.Col1 (qry1.Col1) | qry4.Col2 (qry1.Col2) | qry4.Col3 (qry2.Col2)
----------------------------------------------------------------------
10245.123 | Have | Great
302044.31 | A | Day
If this is all doable in one SQL string, that would be great. If a couple of steps are required, that's okay as well. I just would like to avoid having to time consumingly do this using loops and RecordSet.Findfirst in VBA.
You can use a correlated subquery:
select q1.*,
(select top 1 q2.col2
from qry2 as q2
order by abs(q2.col1 - q1.col1), q2.col2
) as qry2_col2
from qry1 as q1;

SQL statement that retrieves formulas for two different dates in db

All,
I have three total tables. The first table 'rollup1' contains the number of views and number of clicks for a campaign, as well as a one-up number for the day field (largest number in column represents the current date) A second table 'rollup2' contains the earnings for the campaign. It also contains the same one-up number for the dayfield. The third table 'campaigns' contains the ID/names for the campaigns. campaigns.id = rollup1.id = rollup2.id and rollup1.day=rollup2.day
I want to generate an SQL query that lists the campaign id, name, specific calculated value from yesterday, and specific calculated value from today. The specific calculated value I'm looking for is (earnings/clicks)*1000.
The results will look like:
id | name | yesterday | today
a | Campaign1 | $0.05 | $0.010
I think I can use case statements, but I can't seem to get it correct. Here's what I have so far. It calculates the formula for yesterday, but not the one for today. I need these to be side by side.
select campaigns.id, campaigns.name, rollup1.views,rollup1.clicks,rollup2.costs,round((rollup2.costs/rollup1.views)*1000,2) as yesterday
from campaigns,rollup1,rollup2
where campaigns.id = rollup1.campaign_id and campaigns.id = rollup2.campaign_id
and rollup1.dayperiod = rollup2.dayperiod
and rollup1.dayperiod = (SELECT (max(rollup1.dayperiod) -1) FROM rollup1)
Thanks for any help you can provide.

SQL Query with multiple values in one column

I've been beating my head on the desk trying to figure this one out. I have a table that stores job information, and reasons for a job not being completed. The reasons are numeric,01,02,03,etc. You can have two reasons for a pending job. If you select two reasons, they are stored in the same column, separated by a comma. This is an example from the JOBID table:
Job_Number User_Assigned PendingInfo
1 user1 01,02
There is another table named Pending, that stores what those values actually represent. 01=Not enough info, 02=Not enough time, 03=Waiting Review. Example:
Pending_Num PendingWord
01 Not Enough Info
02 Not Enough Time
What I'm trying to do is query the database to give me all the job numbers, users, pendinginfo, and pending reason. I can break out the first value, but can't figure out how to do the second. What my limited skills have so far:
select Job_number,user_assigned,SUBSTRING(pendinginfo,0,3),pendingword
from jobid,pending
where
SUBSTRING(pendinginfo,0,3)=pending.pending_num and
pendinginfo!='00,00' and
pendinginfo!='NULL'
What I would like to see for this example would be:
Job_Number User_Assigned PendingInfo PendingWord PendingInfo PendingWord
1 User1 01 Not Enough Info 02 Not Enough Time
Thanks in advance
You really shouldn't store multiple items in one column if your SQL is ever going to want to process them individually. The "SQL gymnastics" you have to perform in those cases are both ugly hacks and performance degraders.
The ideal solution is to split the individual items into separate columns and, for 3NF, move those columns to a separate table as rows if you really want to do it properly (but baby steps are probably okay if you're sure there will never be more than two reasons in the short-medium term).
Then your queries will be both simpler and faster.
However, if that's not an option, you can use the afore-mentioned SQL gymnastics to do something like:
where find ( ',' |fld| ',', ',02,' ) > 0
assuming your SQL dialect has a string search function (find in this case, but I think charindex for SQLServer).
This will ensure all sub-columns begin and start with a comma (comma plus field plus comma) and look for a specific desired value (with the commas on either side to ensure it's a full sub-column match).
If you can't control what the application puts in that column, I would opt for the DBA solution - DBA solutions are defined as those a DBA has to do to work around the inadequacies of their users :-).
Create two new columns in that table and make an insert/update trigger which will populate them with the two reasons that a user puts into the original column.
Then query those two new columns for specific values rather than trying to split apart the old column.
This means that the cost of splitting is only on row insert/update, not on _every single select`, amortising that cost efficiently.
Still, my answer is to re-do the schema. That will be the best way in the long term in terms of speed, readable queries and maintainability.
I hope you are just maintaining the code and it's not a brand new implementation.
Please consider to use a different approach using a support table like this:
JOBS TABLE
jobID | userID
--------------
1 | user13
2 | user32
3 | user44
--------------
PENDING TABLE
pendingID | pendingText
---------------------------
01 | Not Enough Info
02 | Not Enough Time
---------------------------
JOB_PENDING TABLE
jobID | pendingID
-----------------
1 | 01
1 | 02
2 | 01
3 | 03
3 | 01
-----------------
You can easily query this tables using JOIN or subqueries.
If you need retro-compatibility on your software you can add a view to reach this goal.
I have a tables like:
Events
---------
eventId int
eventTypeIds nvarchar(50)
...
EventTypes
--------------
eventTypeId
Description
...
Each Event can have multiple eventtypes specified.
All I do is write 2 procedures in my site code, not SQL code
One procedure converts the table field (eventTypeIds) value like "3,4,15,6" into a ViewState array, so I can use it any where in code.
This procedure does the opposite it collects any options your checked and converts it in
If changing the schema is an option (which it probably should be) shouldn't you implement a many-to-many relationship here so that you have a bridging table between the two items? That way, you would store the number and its wording in one table, jobs in another, and "failure reasons for jobs" in the bridging table...
Have a look at a similar question I answered here
;WITH Numbers AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS N
FROM JobId
),
Split AS
(
SELECT JOB_NUMBER, USER_ASSIGNED, SUBSTRING(PENDING_INFO, Numbers.N, CHARINDEX(',', PENDING_INFO + ',', Numbers.N) - Numbers.N) AS PENDING_NUM
FROM JobId
JOIN Numbers ON Numbers.N <= DATALENGTH(PENDING_INFO) + 1
AND SUBSTRING(',' + PENDING_INFO, Numbers.N, 1) = ','
)
SELECT *
FROM Split JOIN Pending ON Split.PENDING_NUM = Pending.PENDING_NUM
The basic idea is that you have to multiply each row as many times as there are PENDING_NUMs. Then, extract the appropriate part of the string
While I agree with DBA perspective not to store multiple values in a single field it is doable, as bellow, practical for application logic and some performance issues. Let say you have 10000 user groups, each having average 1000 members. You may want to have a table user_groups with columns such as groupID and membersID. Your membersID column could be populated like this:
(',10,2001,20003,333,4520,') each number being a memberID, all separated with a comma. Add also a comma at the start and end of the data. Then your select would use like '%,someID,%'.
If you can not change your data ('01,02,03') or similar, let say you want rows containing 01 you still can use " select ... LIKE '01,%' OR '%,01' OR '%,01,%' " which will insure it match if at start, end or inside, while avoiding similar number (ie:101).