Below is an existing ms sql server 2008 report query.
SELECT
number, batchtype, customer, systemmonth, systemyear, entered, comment, totalpaid
FROM
payhistory LEFT OUTER JOIN agency ON
payhistory.SendingID = agency.agencyid
WHERE
payhistory.batchtype LIKE 'p%' AND
payhistory.entered >= '2011-08-01 00:00:00.00' AND
payhistory.entered < '2011-08-15 00:00:00.00' AND
payhistory.systemmonth = 8 AND
payhistory.systemyear = 2011 AND
payhistory.comment NOT LIKE 'Elit%'
Results will look like this:
number batchtype customer systemmonth systemyear entered comment totalpaid
6255756 PC EMC1106 8 2011 12:00:00 AM DP From - NO CASH 33
5575317 PA ERS002 8 2011 12:00:00 AM MO-0051381526 7/31 20
6227031 PA FTS1104 8 2011 12:00:00 AM MO-10422682168 7/30 25
6232589 PC FTS1104 8 2011 12:00:00 AM DP From - NO CASH 103
2548281 PC WAP1001 8 2011 12:00:00 AM NCO DP $1,445.41 89.41
4544785 PCR WAP1001 8 2011 12:00:00 AM NCO DP $1,445.41 39
What I am trying to do is modify the query that will exclude records where the customer is like 'FTS%' and 'EMC%' and batchtype = 'PC'. As you can see in the result set there are records where customer is like FTS% and batchtype = 'PA'. I would like to keep these records in the results. I would appreciate any ideas offered.
Your query contains a mix of upper and lower string comparison targets. As far as I'm aware, SQL Server is not by default case-sensitive; is it possible this is what is tripping your query up? Check collation per this answer.
EDIT: Based on your updated question, can you not just use an AND clause that uses a NOT on the front?
In other words, add a 'AND not (x)' clause, where 'x' is the conditions that define the records you want to exclude? You'd need to nest the customer test, because it's an OR.
e.g.:
... payhistory.comment NOT LIKE 'Elit%'
AND not ((customer like 'FTS%' or customer like 'EMC%') AND batchtype = 'PC')
As a side note, I believe that a LIKE clause may imply an inefficient table scan in some (but not all) cases, so if this query will be used in a performance-sensitive role you may want to check the query plan, and optimise the table to suit.
$sql="select * from builder_property where builder_pro_name LIKE '%%' OR builder_pro_name LIKE '%za%' AND status='Active'";
This will return all the builder property name in table that will ends name like plaza or complex.
It can be because your sever might be case sensitive. In that case, below query would work.
SELECT
table1.number, table1.btype, table1.cust, table1.comment, table2.ACode
FROM
table1 LEFT OUTER JOIN table2 ON table1.1ID = table2.2ID
WHERE
lower(table1.btype) LIKE 'p%' AND
lower(table1.comment) NOT LIKE 'yyy%' AND
lower(table1.cust) NOT LIKE 'abc%' AND
lower(table1.cust) NOT LIKE 'xyz%' AND
lower(table1.btype) <> 'pc'
Add this condition to the WHERE clause:
NOT((customer LIKE 'FTS%' OR customer LIKE 'EMC%') AND batchtype='PC')
Assuming your other results are OK and you just want to filter those out, the whole query would be
SELECT
number, batchtype, customer, systemmonth, systemyear, entered, comment, totalpaid
FROM
payhistory
LEFT OUTER JOIN agency ON
payhistory.SendingID = agency.agencyid
WHERE
payhistory.batchtype LIKE 'p%' AND
payhistory.entered >= '2011-08-01 00:00:00.00' AND
payhistory.entered < '2011-08-15 00:00:00.00' AND
payhistory.systemmonth = 8 AND
payhistory.systemyear = 2011 AND
payhistory.comment NOT LIKE 'Elit%' AND
NOT((payhistory.customer LIKE 'FTS%' OR payhistory.customer LIKE 'EMC%') AND payhistory.batchtype='PC')
Hope that works for you.
When building complex where clauses it is a good idea to use parenthesis to keep everything straight. Also when using multiple NOT LIKE statements you have to combine all of the NOT LIKE conditions together using ORs and wrap them inside of a separate AND condition like this...
WHERE
(payhistory.batchtype LIKE 'p%')
AND (payhistory.entered >= '2011-08-01 00:00:00.00')
AND (payhistory.entered < '2011-08-15 00:00:00.00')
AND (payhistory.systemmonth = 8 )
AND (payhistory.systemyear = 2011)
AND ( // BEGIN NOT LIKE CODE
(payhistory.comment NOT LIKE 'Elit%')
OR (
(payhistory.customer NOT LIKE 'EMC%') AND
(payhistory.batchtype = 'PC')
)
OR (
(payhistory.customer NOT LIKE 'FTS%') AND
(payhistory.batchtype = 'PC')
)
) //END NOT LIKE CODE
Related
What do I have to change to get different results from different names.The table should give me the debts of each of them, this is calculated by the amount and the price of the drink. Now it should show all the names with the corresponding invoice that happens after the select
%sql select name, sum(getraenk.preis*schulden.menge) schulden from schulden \
join person on (fk_person = person.id)\
join getraenk on (fk_getraenk = getraenk.id)\
where name like ("dani")
Edit: it should spend all the names with their debts, that is:
dani = 8.5
michael = 12.5
...
Just in case your problem is very simple, you should be able to see all names and values with an SQL that looks like this:
select name, getraenk.preis*schulden.menge schulden
from schulden
join person on (fk_person = person.id)
join getraenk on (fk_getraenk = getraenk.id)
Note that I removed the where clause... this was the part that limited it to one name.
You also don't need the sum clause here unless you are doing a group by
Have you considered simply using GROUP BY name at the end of this query?
https://www.w3schools.com/sql/sql_groupby.asp
This will give you the sum of total debt for all names in your table which sounds like the result you are looking for.
You're missing
GROUP BY name
in the query.
I am trying to make a filter to find all the stuffs made of various substances.
In the database, there is:
a stuffs table
a substances table
a stuffs_substances join table.
Now, I want to find only all the stuffs that are made of gold AND silver (not all the stuffs that contain gold and all stuffs that contain silver).
One last thing: the end user can type only a part of the substance name in the filter form field. For example he will type silv and it will show up all the stuffs made of silver.
So I made this query (not working):
select "stuffs".*
from "stuffs"
inner join "stuffs_substances" as "substances_join"
on "substances_join"."stuff_id" = "stuffs"."id"
inner join "substances"
on "substances_join"."substance_id" = "substances"."id"
where ("substances"."name" like '%silv%')
and ("substances"."name" like '%gold%')
It returns an empty array. What am I doing wrong here?
Basically, you just want aggregation:
select st.*
from "stuffs" st join
"stuffs_substances" ss join
on ss."stuff_id" = st."id" join
"substances" s
on ss."substance_id" = s."id"
where s."name" like '%silv%' or
s."name" like '%gold%'
group by st.id
having count(*) filter (where s."name" like '%silv%') > 0 and
count(*) filter (where s."name" like '%gold%') > 0;
Note that this works, assuming that stuff.id is the primary key in stuffs.
I don't understand your fascination with double quotes and long table aliases. To me, those things just make the query harder to write and to read.
if you want to do search by part of word then do action to re-run query each time user write a letter of word , and the filter part in query in case of oracle sql way
in case to search with start part only
where name like :what_user_write || '%'
or in case any part of word
where name like '%' || :what_user_write || '%'
you can also use CAB, to be sure user can search by capital or small whatever
ok, you ask about join, I test this in mysql , it work find to get stuff made from gold and silver or silver and so on, hope this help
select sf.id, ss.code, sf.stuff_name from stuffs sf, stuffs_substances ss , substances s
where sf.id = ss.id
and s.code = ss.code
and s.sub_name like 'gol%'
I have the following code:
UPDATE tableOne
SET columnOne = CASE
WHEN tableOne.columnTwo LIKE '%-02-%' OR tableOne.columnTwo LIKE '%-03-%' OR
tableOne.columnTwo LIKE '%-04-%' OR
tableOne.columnTwo LIKE '%-05-%' OR
tableOne.columnTwo LIKE '%-06-%' OR
tableOne.columnTwo LIKE '%-07-%' OR tableOne.columnTwo LIKE '%-08-%' OR
tableOne.columnTwo LIKE '%-09-%'
THEN tableTwo.columnOne :: text
ELSE tableOne.columnOne
END
FROM tableTwo
WHERE tableTwo.tableId = tableOne.tableId
I have two tables. tableOne consists of 100 millions of rows (and 40 columns) and tableTwo consists of 90 millions of rows. Above query is already in progress for more than 2 days. I am not sure it will ever finish. Is there a way to optimize the query?
If helpful LIKE does the following:
Checks if the string (e.g. 2018-06-30 08:20:17) has listed month. If yes, pick value from tableTwo (and CAST it to type text), else keep self value (already type text).
Move the case condition to the where clause:
UPDATE tableOne
SET columnOne = tableTwo.columnOne::text
FROM tableTwo
WHERE tableTwo.tableId = tableOne.tableId AND
tableOne.columnTwo ~ '-0[2-9]-' and
tableOne.columnOne is distinct from tableTwo.columnOne::text;
Regular expressions are not really that much faster than a bunch of likes. The win here is in not updating rows that don't need to be updated. If the format of tableOne.columnTwo is a known format, you could use substring operations instead.
What about only updating if month is between 02 and 09
UPDATE tableOne
SET columnOne = tableTwo.columnOne :: text
FROM tableTwo
WHERE tableTwo.tableId = tableOne.tableId
AND SUBSTRING(tableOne.columnTwo FROM 6 FOR 2) BETWEEN '02' AND '09'
I am working on a classroom reservation tool. A core component is the ability to compare the requested date range to the existing reservations, to ensure that there is no overlap. I've read through several date range related questions here, and studied Salman's explanation and implementation of Allen's interval algebra ( SQL Query to Find Overlapping (Conflicting) Date Ranges ) until I understood it. Here's a stripped-down version of what I came up with.
tblRooms
roomID room
5 110
30 178
tblReservations
reservedID fkRoom dateIn dateOut
1 5 3/10/2017 3/15/2017
2 5 3/1/2017 3/3/2017
4 5 4/1/2017 4/30/2017
SELECT DISTINCTROW tblRooms.roomID, tblRooms.room
FROM tblRooms LEFT JOIN tblReservations
ON tblRooms.roomID = tblReservations.fkRoom
WHERE NOT Exists (
SELECT DISTINCT tblRooms.roomID
FROM tblRooms
WHERE ((tblReservations.[dateOut] >= #3/3/2017#)
AND (#3/9/2017# >= tblReservations.[dateIn])));
I'm getting inconsistent returns. These dates will exclude room 110, as they should. Other test input (#3/4/2017# and #3/10/2017#, #4/1/2017# and #4/14/2017#) won't. I've tried combinations of "WHERE NOT (...", "WHERE Exists () = False", etc.
I work on a highly restrictive network, where I can't pull in templates at will - my only options when I create a database are "Blank" and "Web", so I've got to roll my own on this. I appreciate any assistance.
Can you try the following:
SELECT DISTINCTROW tblRooms.roomID, tblRooms.room
FROM tblRooms
WHERE NOT Exists (
SELECT 1
FROM tblReservations
WHERE
tblReservations.fkRoom = tblRooms.roomID
AND ((tblReservations.[dateOut] >= #3/3/2017#)
AND (#3/9/2017# >= tblReservations.[dateIn])));
For a reservation check query you would do this:
select ...
from tblRooms room
where not exists
( select *
from tblReservations r
where r.fkRoom = room.roomId and
end > r.[datein] and start < r.[dateout] );
BUT the important part is, pass those end and start as parameters instead of hardcoded values like you did. With hardcoded values you are always open to get wrong results or error. For example what is:
#3/9/2017# really? Its interpretation would depend on regional settings (I am not an access programmer so I might be wrong).
I want to create a graph that pulls data from 2 user questions generated from within an SQL database.
The issue is that the user questions are stored in the same table, as are the answers. The only connection is that the question string includes a year value, which I extract using the LEFT command so that I output a column called 'YEAR' with a list of integer values running from 2013 to 2038 (25 year period).
I then want to pull the corresponding answers ('forecast' and 'actual') from each 'YEAR' so that I can plot a graph with a couple of values from each year (sorry if this isn't making any sense). The graph should show a forecast line covering the 25 year period with a second line (or column) showing the actual value as it gets populated over the years. I'll then be able to visualise if our actual value is close to our original forecast figures (long term goal!)
CODE BELOW
SELECT CAST((LEFT(F_TASK_ANS.TA_ANS_QUESTION,4)) AS INTEGER) AS YEAR,
-- first select takes left 4 characters of question and outputs value as string then coverts value to whole number.
CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%forecast' THEN F_TASK_ANS.TA_ANS_ANSWER END) AS NUMERIC(9,2)) AS 'FORECAST',
CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%actual' THEN ISNULL(F_TASK_ANS.TA_ANS_ANSWER,0) END) AS NUMERIC(9,2)) AS 'ACTUAL'
-- actual value will be null until filled in each year therefore ISNULL added to replace null with 0.00.
FROM F_TASK_ANS INNER JOIN F_TASKS ON F_TASK_ANS.TA_ANS_FKEY_TA_SEQ = F_TASKS.TA_SEQ
WHERE TA_ANS_ANSWER <> ''
AND (TA_TASK_ID LIKE '%6051' OR TA_TASK_ID LIKE '%6052')
-- The two numbers above refer to separate PPM questions that the user enters a value into
I tried GROUP BY 'YEAR' but I get an
Error: Each GROUP BY expression must contain at least one column that
is not an outer reference - which I assume is because I haven't linked
the 2 tables in any way...
Should I be adding a UNION so the tables are joined?
What I want to see is something like the following output (which I'll graph up later)
YEAR FORECAST ACTUAL
2013 135000 127331
2014 143000 145102
2015 149000 0
2016 158000 0
2017 161000 0
2018... etc
Any help or guidance would be hugely appreciated.
Thanks
Although the syntax is pretty hairy, this seems like a fairly simple query. You are in fact linking your two tables (with the JOIN statement) and you don't need a UNION.
Try something like this (using a common table expression, or CTE, to make the grouping clearer, and changing the syntax for slightly greater clarity):
WITH data
AS (
SELECT YEAR = CAST((LEFT(A.TA_ANS_QUESTION,4)) AS INTEGER)
, FORECAST = CASE WHEN A.TA_ANS_QUESTION LIKE '%forecast'
THEN CONVERT(NUMERIC(9,2), A.TA_ANS_ANSWER)
ELSE CONVERT(NUMERIC(9,2), 0)
END
, ACTUAL = CASE WHEN A.TA_ANS_QUESTION LIKE '%actual'
THEN CONVERT(NUMERIC(9,2), ISNULL(A.TA_ANS_ANSWER,0) )
ELSE CONVERT(NUMERIC(9,2), 0)
END
FROM F_TASK_ANS A
INNER JOIN F_TASKS T
ON A.TA_ANS_FKEY_TA_SEQ = T.TA_SEQ
-- It sounded like you wanted to include the ones where the answer was null. If
-- that's wrong, get rid of the test for NULL.
WHERE (A.TA_ANS_ANSWER <> '' OR A.TA_ANS_ANSWER IS NULL)
AND (TA_TASK_ID LIKE '%6051' OR TA_TASK_ID LIKE '%6052')
)
SELECT YEAR
, FORECAST = SUM(data.Forecast)
, ACTUAL = SUM(data.Actual)
FROM data
GROUP BY YEAR
ORDER BY YEAR
Try something like this ...
SELECT CAST((LEFT(F_TASK_ANS.TA_ANS_QUESTION,4)) AS INT) AS [YEAR]
,SUM(CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%forecast'
THEN F_TASK_ANS.TA_ANS_ANSWER ELSE 0 END) AS NUMERIC(9,2))) AS [FORECAST]
,SUM(CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%actual'
THEN F_TASK_ANS.TA_ANS_ANSWER ELSE 0 END) AS NUMERIC(9,2))) AS [ACTUAL]
FROM F_TASK_ANS INNER JOIN F_TASKS
ON F_TASK_ANS.TA_ANS_FKEY_TA_SEQ = F_TASKS.TA_SEQ
WHERE TA_ANS_ANSWER <> ''
AND (TA_TASK_ID LIKE '%6051' OR TA_TASK_ID LIKE '%6052')
GROUP BY CAST((LEFT(F_TASK_ANS.TA_ANS_QUESTION,4)) AS INT)