find rows with specific condition on the columns - sql

I'm trying to make an sql query where I will compare all rows to each other and check their columns. using condition I will display the need rows.
I made this one and I got an error message "UNKNOWN COLUMN" , any ideas how to fix it?
select * from table1 as tb1 where DATE_FORMAT(start_datetime, '%H:%i:%s') in (
select DATE_FORMAT(start_datetime, '%H:%i:%s') from table1 as tb2
group by DATE_FORMAT(start_datetime, '%H:%i:%s') having count(*) > 2 AND (end_datetime = start_datetime) OR (tb1.code = tb2.code)
) AND user_id = 1
to explain what I wanna do,I'm searching the rows that have the same time then if the start_datetime is equal to the end_datetime or the rows have the same code
in this
example my sql query should return the last 4 rows, 2 because they have the same start_datetime and end_datetime and 2 because the have the same time on the start_datetime , the same code and the end_datetime is NULL

you can use "union all" operator between 2 data sets
select code,start_datetime,end_datetime from table2
where start_datetime=end_datetime
union all
select t2.code,t2.start_datetime,t2.end_datetime from
(
select code,start_datetime,end_datetime from table2
where start_datetime!=end_datetime
and end_datetime is null
) as t2
inner join ( select code table2 group by DATE_FORMAT(start_datetime, '%H:%i:%s'),code having count(*)>=2 )as t1 on t2.code=t1.code

Notwithstanding any errors we can't see because you haven't provided the schema, "fs1.code" and "fs2.code" do not seem to reference table aliases that have been defined in the statement. The aliases that do get defined are "tb1" and "tb2" and they don't match.

Related

SQL if statement to select items form different tables

I am creating a new table joining 3 different tables. The problem is that I have some data that I want to select for other_info divided into two different tables. table_1 has preference over table_2, but it is possible that in table_1 are missing values. So, I want to select the value of box if it's not empty from table_1 and select it from table_2 if the value in table_1 does not exist.
This is the code I have very simplified, but I think it's enough to see what I want to do. I've written an IF ... ELSE statement inside a with, and this is the error I get:
Syntax error: Expected "(" or keyword SELECT or keyword WITH but got keyword IF at [26:5]
Besides, I've tried different things inside the conditional of the if, but none of them is what I expect. Here is the code:
CREATE OR REPLACE TABLE `new_table`
PARTITION BY
Current_date
AS (
WITH info AS (
SELECT
Date AS Day,
Box,
FROM
`table_1`
),
other_info AS (
IF (...)
BEGIN{
SELECT
Date AS Day,
Box
FROM
`table_1`}
END
ELSE
BEGIN{
SELECT
Date AS Day,
Box
FROM
`table_2`}
END
)
SELECT
Date
Box
Box_description
FROM
`table_3`
LEFT JOIN info(Day)
LEFT JOIN other_info(Day)
)
You're not going to be able to embed an IF within a CTE or a Create-Table-As.
An alternative structure can be to union two queries with mutually exclusive WHERE clauses... (Such that only one of the two queries ever returns anything.)
For example, if the code below, something is checked for being NULL or NOT NULL, and so only one of the two can ever return data.
WITH
info AS
(
SELECT
Date AS Day,
Box,
FROM
`table_1`
),
other_info AS
(
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
THIS BIT
--------------------------------------------------------------------------------
SELECT
Date AS Day,
Box
FROM
`table_1`
WHERE
(SELECT MAX(x) FROM y) IS NULL
UNION ALL
SELECT
Date AS Day,
Box
FROM
`table_2`
WHERE
(SELECT MAX(x) FROM y) IS NOT NULL
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
)
SELECT
Date
Box
Box_description
FROM
`table_3`
LEFT JOIN info(Day)
LEFT JOIN other_info(Day)
In stead of the if..., you could do something like this (in MySQL):
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2 WHERE `date` NOT IN (SELECT `date` FROM table1)
I am not sure (as in: I did not test), but I do think this is also possible in google-bigquery
see: DBFIDDLE

Need help in sql Query.neo

In this table there are three colum and in need the value for of data which are lesser than code = 28,this is my query
SELECT value,code,date
FROM table
order by date,vchcode
but when i ad where clouse like
SELECT value,code,date
FROM table
where code < 28
order by date,vchcode
is only shows 2 row with code 26 and 27... i need 26,27 and 32.. and table colums are variable its not fix..
I think you wnat to take the date into account -- what you really want are all rows before the date of the row with code 28.
One method uses a subquery:
SELECT t.value, t.code, t.date
FROM table t
WHERE date < (SELECT date FROM table t2 WHERE t2.code = 28)
ORDER BY t.date, t.vchcode

Select left 10 numbers, left join for a price from second table, and then sum, SQL

I am currently working in sql 2012 visual management studio. I have two tables. Table1 has three columns (ItemNumber as varchar, Quantity as int, and TimeOrdered as datetime). Table2 has 2 columns (ItemNumber as varchar, and Price as float). Please note these item numbers are not the same, the part numbers on table 1 have a letter after the number while the table 2 item number does not. For example on table 1 the item number will look something like this 999999999-E and the other table will just be 999999999-. Therefore I must use a select Left for 10 digits to get the part number.
I need to pull a list of item numbers from table 1 based on the time ordered and then cross compare that list to table 2 and multiple the price times the quantity for a grand total. Here is my code so far:
SELECT sum(tbl.quantity * table2.price) as grandtotal,
tbl.PartNumber,
tbl.quanity,
table2.price
FROM
(SELECT left(itemnumber, 10) as itemnumber, quantity
FROM table1
WHERE TimeOrdered between
('2014-05-05 00:00:00.000')
AND
('2015-05-05 00:00:00.000')) as tbl
Left table2 on
tbl.partnumber =tbl2.itemnumber
I am receiving an error here for aggregate columns but I am not sure this is the correct way to go about this to begin with.
-------------update---------------
I got it working. Sorry for taking so long to get back to you guys, I was stuck in a meeting all day,
How About This. The case is just to avoid div by Zero errors.
SELECT sum( Isnull(tbl.quantity,0) * Isnull(table2.price,0) ) as grandtotal,
tbl.PartNumber,
Sum(tbl.quanity),
case when Isnull(Sum(tbl.quanity),0) = 0 then null else
sum(Isnull(tbl.quantity,0) * Isnull(table2.price,0) ) / Sum(tbl.quanity) end
as Price
FROM
(SELECT left(itemnumber, 10) as itemnumber, quantity FROM table1 WHERE TimeOrdered between
('2014-05-05 00:00:00.000')
AND ('2015-05-05 00:00:00.000')) as tbl
Left outer join table2 on
tbl.partnumber =tbl2.itemnumber
group by tbl.PartNumber
SQL server requires you to explicitly group by the columns you're not aggregating by. So you need to add group by tbl.PartNumber, tbl.quantity, table2.price. Of course, that's probably going to make the tbl.quantity * table2.price kind of useless. What are you actually trying to do? :)
Here is a fiddle with some sample data that should give you what you want. You need to include any non-aggregate columns in your group by.
Your code ends up as follows:
SELECT left(table1.ItemNumber, 10) as PartNumber,
table2.price,
sum(table1.quantity) as totalquantity,
sum(table1.quantity * table2.price) as grandtotal
FROM table1
INNER JOIN table2 ON left(table1.ItemNumber, 10) = table2.ItemNumber
WHERE t1.Timerordered BETWEEN '2014-05-05 00:00:00.000' AND '2015-05-05 00:00:00.000'
GROUP BY table1.ItemNumber, table2.price
SQL Fiddle Example
SELECT SUM(t1.quantity * t2.price) AS 'GrandTotal'
,SUM(t1.quantity) AS 'Quantity'
,t1.itemnumber
,t2.price
FROM Table1 t1
JOIN Table2 t2 ON LEFT(t1.itemnumber, 10) = t2.itemnumber
WHERE t1.Timeordered BETWEEN '2014-05-05 00:00:00.000' AND '2015-05-05 00:00:00.000'
GROUP BY t1.itemnumber, t2.price

SQL query - Selecting distinct values from a table

I have a table in which i have multiple entries against a FK. I want to find out the value of FK which do not have certain entries e.g
my table has following entries.
PK----------------FK-----------------Column entries
1----------------100-----------------ab1
2----------------100-----------------ab2
3----------------100-----------------ab4
4----------------200-----------------ab1
5----------------200-----------------ab2
6----------------200-----------------ab3
7----------------300-----------------ab1
8----------------300-----------------ab2
9----------------300-----------------ab3
10---------------300-----------------ab4
Now, from this table i want to filter all those FK which do not have ab3 or ab4 in them. Certainly, i expect distinct values i.e. in this case result would be FK= 100 and 200.
The query which i am using is
select distinct(FK)
from table1
where column_entries != 'ab3'
or column_entries != 'ab4';
Certainly, this query is not fetching the desired result.
try the following :-
select distinct fk_col from table1
minus
(select distinct fk_col from table1 where col_entry='ab3'
intersect
select distinct fk_col from table1 where col_entry='ab4')
This will show all those FKs which do not have 'ab3' and 'ab4'. i.e. 100 and 200 in your case
The below script may be the solution if I got your question in a right way.
SELECT DISTINCT(TableForeignKey)
FROM Test
WHERE TableForeignKey NOT IN (
SELECT T1.TableForeignKey
FROM Test T1 INNER JOIN Test T2 ON T1.TableForeignKey = T2.TableForeignKey
WHERE T1.TableEntry = 'ab3' AND T2.TableEntry = 'ab4')
SQLFiddle Demo
You could use GROUP BY with conditional aggregation in HAVING:
SELECT FK
FROM table1
GROUP BY FK
HAVING COUNT(CASE column_entries WHEN 'ab3' THEN 1 END) = 0
OR COUNT(CASE column_entries WHEN 'ab4' THEN 1 END) = 0
;
The two conditional aggregates count 'ab3' and 'ab4' entries separately. If both end up with results greater than 0, then the corresponding FK has both 'ab3' and 'ab4' and is thus not returned. If at least one of the counts evaluates to 0, then FK is considered satisfying the requirements.

update a field based on subtotal from another table

I'm using oracle(10).
I've got two tables as follows:
Table1 (uniq rows):
ID AMOUNT DATE
Table2:
ID AMOUNT1 AMOUNT2 ...AMOUNTN DATE
Table2 is connected many to one to Table1 connected via ID.
What I need is update-ing Table1.DATE with: the last (earliest) date from Table2 where Table1.AMOUNT - SUM(Table2.AMOUNT1) <= 0, when reading table 2 backwards by the Table2.DATE field.
Is there a simple way to do it?
Thanks in advance!
UPDATE: as I see from your answers I had misspecified the question a bit. So here goes a detailed example:
Table1 has:
ID: 1 AMOUNT:100 DATE:NULL
Table2 has (for ID: 1 so ID is not listed in here):
AMOUNT1 DATE
50 20080131
30 20080121
25 20080111
20 20080101
So in this case I need 20080111 as the DATE in Table1 as 50+30+25 => 100.
Based on your revised question, this is a case for using analytic functions.
Assuming you meant >=100 rather than <= 100 as your example implies, and renaming columns DATE to THEDATE since DATE is a reserved word in Oracle:
update table1 set thedate=
( select max(thedate) from
( select id, thedate,
sum(amount1) over (partition by id order by thedate desc) cumsum
from table2
) v
where v.cumsum >= 100
and v.id = table1.id
)
If the 100 means the current value of table1 then change that line to:
where v.cumsum >= table1.amount
First off - your database layout feels severely wrong, but I guess you can't / don't want to change it. Table1 should probably be a view, and Table2 does not make the impression of proper normalization. Something like (ID, AMOUNT_TYPE, AMOUNT_VALUE, DATE) would make much more sense to me.
But to solve your problem (this is T-SQL "UPDATE FROM" syntax, but I think Oracle knows it):
UPDATE
Table1
SET
Date = Table2Aggregate.MinDate
FROM
Table1
INNER JOIN (
SELECT Id, SUM(Amount1) SumAmount1, MIN(Date) MinDate
FROM Table2
GROUP BY Id
) AS Table2Aggregate ON Table1.Id = Table2Aggregate.ID
WHERE
Table1.Amount - Table2Aggregate.SumAmount1 <= 0