SQL query with multiple excludes not working - sql-server-2008

I'm trying to extract accounts that owe $25 or more and have been sent to collections, but I need to exclude accounts which have certain stopID blocks on them. I'm getting about a 70% success rate with the query I've written, but it still includes many of the records that have the StopID's on the exclusion statement. I'm not sure which direction to go from here - any suggestions?
select DISTINCT
Polaris.Patrons.Barcode as BARCODE,
Polaris.PatronRegistration.NameLast AS [LAST NAME],
Polaris.PatronRegistration.NameFirst AS [FIRST NAME],
Polaris.PatronRegistration.NameMiddle AS [MIDDLE NAME],
cast(Patrons.ChargesAmount as decimal(22,2)) AS AMOUNT,
Polaris.Addresses.StreetOne AS ADDRESS,
Polaris.PostalCodes.City AS CITY,
Polaris.PostalCodes.State AS STATE,
Polaris.PostalCodes.PostalCode AS ZIP,
Cast (PatronRegistration.Birthdate AS DATE) AS DOB
from Polaris.PatronRegistration TABLESAMPLE SYSTEM(6 PERCENT) inner join
Polaris.Patrons on PatronRegistration.PatronID = Polaris.Patrons.PatronID left join
Polaris.PatronAddresses on PatronRegistration.PatronID = PatronAddresses.PatronID left join
Polaris.Addresses on PatronAddresses.AddressID = Polaris.Addresses.AddressID left join
Polaris.PostalCodes ON Polaris.Addresses.PostalCodeID = Polaris.PostalCodes.PostalCodeID left outer join
Polaris.PatronStops ON Polaris.Patrons.PatronID = Polaris.PatronStops.PatronID left outer join
Polaris.PatronStopDescriptions ON Polaris.PatronStops.PatronStopID = Polaris.PatronStopDescriptions.PatronStopID
where Patrons.OrganizationID in (1,2,3,4,5,6,7,8,9,10,11,12,13) --All Organizations
and Patrons.PatronCodeID in (1,2,4,5,6,8,9,14,15) --All patron types except FOL,Minor,Staff,Volunteer,NRC,WWR,Minor E-Card
and Patrons.ChargesAmount >= 25.00 --Accounts with balance of $25 or more
and Patrons.SystemBlocks in (1024) --Accounts have been sent to Collections block
and NOT (Polaris.PatronStops.PatronStopID in (7,13,14,15,16)) --Accounts contain any of these StopID codes
order by NameLast asc,NameFirst asc,NameMiddle asc

Related

"The multi-part identifier 'xxx' could not be bound" when attempting to join three tables

I'd like to start off with the fact that I'm a SQL beginner with only 5 or 6 hours of experience. I'm learning fast though.
Ultimately I am trying to select the addresses of clients by product line. The first table (arinvch) contains invoices and therefore the addresses of the clients; the second table (aritrsh) contains the individual line items of the invoices of table 1, and the third table (icitemh) contains the product lines of the line items.
I attempted to join tables two and three in a subquery first to extract the product lines, then join that with the first table to get the customer addresses by product line.
Simply put, this is what I tried to do:
SELECT
table1.addressinfo
FROM
table1
INNER JOIN
(SELECT * FROM
table2 INNER JOIN table3
ON table2.itemnumber = table3.itemnumber
WHERE table3.type = 'CRM') joinedtable
ON
table1.customernumber = joinedtable.customernumber;
The exact code:
SELECT
arinvch.ccustno AS [Customer #],
arinvch.dinvoice AS [Invoice Date],
arinvch.cbcompany AS [Bill to Company],
arinvch.cbaddr1 AS [Bill to Address 1],
arinvch.cbaddr2 AS [Bill to Address 2],
arinvch.cbcity AS [Bill to City],
arinvch.cbstate AS [Bill to State],
arinvch.cbzip AS [Bill to Zip Code],
arinvch.cbcountry AS [Bill to Country],
arinvch.cbphone AS [Bill to Phone],
arinvch.cscompany AS [Ship To Company],
arinvch.csaddr1 AS [Ship To Address 1],
arinvch.csaddr2 AS [Ship To Address 2],
arinvch.cscity AS [Ship To City],
arinvch.csstate AS [Ship To State],
arinvch.cszip AS [Ship To Zip Code],
arinvch.cscountry AS [Ship To Country],
arinvch.csphone AS [Ship To Phone],
arinvch.cscontact AS [Ship To Contact],
aritrsh.cinvno AS [Invoice #],
aritrsh.citemno AS [Item Number],
icitemh.citemno AS [Item #]
FROM
arinvch
INNER JOIN
(SELECT
aritrsh.clineitem
FROM
aritrsh
INNER JOIN
icitemh
ON
aritrsh.citemno = icitemh.citemno
WHERE icitemh.ctype = 'CRM')table2
ON
arinvch.ccustno = aritrsh.ccustno;
This returns the following error message (in FlySpeed SQL):
[FireDAC][Phys][ODBC][Microsoft][ODBC SQL Server Driver][SQL Server]The
multi-part identifier "aritrsh.ccustno" could not be bound.
Thanks in advance!
(Also, as a side goal, if you could also explain how I can get the addresses to not repeat when I pull them from the invoices that would be great. I've tried incorporating SELECT DISTINCT in numerous places but can't seem to work out a solution (as I only want the table1.customernumber to be distinct and WHERE DISTINCT isn't a thing).)
You don't need the subquery:
FROM arinvch INNER JOIN
aritrsh
ON arinvch.ccustno = aritrsh.ccustno INNER JOIN
icitemh
ON aritrsh.citemno = icitemh.citemno AND icitemh.ctype = 'CRM'
The logic is simpler to understand without subqueries. I would use table aliases for the query:
FROM arinvch n INNER JOIN
aritrsh t
ON n.ccustno = t.ccustno INNER JOIN
icitemh i
ON t.citemno = i.citemno AND i.ctype = 'CRM'
These make it easier to write and read the query.
arinvch
JOIN (
SELECT aritrsh.clineitem
FROM aritrsh
JOIN icitemh ON
aritrsh.citemno = icitemh.citemno
WHERE icitemh.ctype = 'CRM'
) table2 ON
arinvch.ccustno = aritrsh.ccustno;
the second table is table2 in your example, not aritrsh.
For the second part:
arinvch (1:M) -> aritrsh and
aritrsh (1:1) -> icitemh
aritrsh will have 1 or more products ordered by customers. This will repeat the address fields for each product ordered. You could summarize the entire thing by putting the entire select statement in parentheses then use group by to remove the invoice records.
select a, b, c, d
from ( big select statement above ) A
group by a, b, c, d
the group by will remove duplicates (just like distinct.) Replace a,b,c,d with the names of your fields in the inner select without prefixes like aritrsh., but only have the fields that have to do with the address and the products, not the invoice lines.

avoid duplicate data when multiple left join

This is my sql select statement http://www.sqlfiddle.com/#!9/353e82/1,
This is the output
I use left join but the data will duplicate on output.
What I want is the data wont duplicate and only show once
Earnings
Total OT Pay - amount
Transport - amount
Uniform - amount
Deduction
Loan - amount
Unpaid Leave - amount
Thanks
If you want single row based on payslip_no then use below query-
SELECT
hrms_salary_payment.`payslip_no` AS payslip_no,
hrms_salary_payment.`payment_month` AS payment_month,
hrms_salary_payment.`basic_salary` AS basic_salary,
hrms_salary_payment.`hours_worken_week` AS hours_worken_week,
hrms_salary_payment.`ot_hours_worked` AS ot_hours_worked,
hrms_salary_payment.`total_ot_pay` AS total_ot_pay,
hrms_salary_payment.`employee_cpf` AS employee_cpf,
hrms_salary_payment.`employer_cpf` AS employer_cpf,
hrms_salary_payment.`sdl_payable` AS sdl_payable,
hrms_salary_payment.`net_salary` AS net_salary,
hrms_salary_payment.`payment_amount` AS payment_amount,
hrms_salary_payment.`payment_date` AS payment_date,
hrms_salary_additional.`item_remark` AS income,
hrms_salary_additional.`item_amount` AS income_amount,
hrms_salary_additional.`isCPF` AS isCPF,
hrms_salary_deduction.`deduction_remark` AS deduction_remark,
hrms_salary_deduction.`deduction_amount` AS deduction_amount
FROM `hrms_salary_payment`
LEFT JOIN `hrms_salary_additional` ON hrms_salary_additional.payment_id = hrms_salary_payment.payment_id
LEFT JOIN `hrms_salary_deduction` ON hrms_salary_deduction.payment_id = hrms_salary_payment.payment_id
where hrms_salary_payment.`payment_id` = 27
GROUP BY hrms_salary_payment.`payslip_no`;
But if you want 3 rows further distinquished by item_remarks then use below query-
SELECT
hrms_salary_payment.`payslip_no` AS payslip_no,
hrms_salary_payment.`payment_month` AS payment_month,
hrms_salary_payment.`basic_salary` AS basic_salary,
hrms_salary_payment.`hours_worken_week` AS hours_worken_week,
hrms_salary_payment.`ot_hours_worked` AS ot_hours_worked,
hrms_salary_payment.`total_ot_pay` AS total_ot_pay,
hrms_salary_payment.`employee_cpf` AS employee_cpf,
hrms_salary_payment.`employer_cpf` AS employer_cpf,
hrms_salary_payment.`sdl_payable` AS sdl_payable,
hrms_salary_payment.`net_salary` AS net_salary,
hrms_salary_payment.`payment_amount` AS payment_amount,
hrms_salary_payment.`payment_date` AS payment_date,
hrms_salary_additional.`item_remark` AS income,
hrms_salary_additional.`item_amount` AS income_amount,
hrms_salary_additional.`isCPF` AS isCPF,
hrms_salary_deduction.`deduction_remark` AS deduction_remark,
hrms_salary_deduction.`deduction_amount` AS deduction_amount
FROM `hrms_salary_payment`
LEFT JOIN `hrms_salary_additional` ON hrms_salary_additional.payment_id = hrms_salary_payment.payment_id
LEFT JOIN `hrms_salary_deduction` ON hrms_salary_deduction.payment_id = hrms_salary_payment.payment_id
where hrms_salary_payment.`payment_id` = 27
GROUP BY hrms_salary_payment.`payslip_no`, hrms_salary_additional.`item_remark`;

counting methodolegy in SQL Server query

Good day everyone…
I have a database that has the following:
Division table that linked to Employee table.
Group table, i.e. courses categories, that linked to Courses table.
and these table linked together thru Curses_Employee table .
so far I managed to come up with a query that give me the number of users who toke certain course in each group/category like the following output table:
groupName | DivisionName| courseName|Total Number of Participants
and here is my query for the above scheme:
SELECT dbo.groups.GroupName, dbo.Divisions.DivisionName, dbo.courses.CourseName, COUNT(dbo.employee_courses.courseId) AS [Total Number of Participants]
FROM dbo.employee AS employee_1 INNER JOIN
dbo.Divisions ON employee_1.DivisionCode = dbo.Divisions.SapCode INNER JOIN
dbo.employee_courses ON employee_1.Username = dbo.employee_courses.employeeId INNER JOIN
dbo.courses ON dbo.employee_courses.courseId = dbo.courses.CourseID INNER JOIN
dbo.groups ON dbo.courses.GroupID = dbo.groups.ID
WHERE (dbo.courses.GroupID = 2)
GROUP BY dbo.courses.CourseID, dbo.courses.CourseName, dbo.Divisions.DivisionName, dbo.groups.GroupName
now I want to add two columns the total number of employee in each division as well as the % like the following table:
groupName | DivisionName| courseName|Total Number of Participants |Total Number of Employee |%
I tried this query but it give me an error:
SELECT dbo.groups.GroupName, dbo.Divisions.DivisionName, dbo.courses.CourseName, COUNT(dbo.employee_courses.courseId) AS [Total Number of Participants],
(SELECT COUNT(Name) AS Expr1
FROM dbo.employee
WHERE (DivisionCode = employee_1.DivisionCode)
GROUP BY DivisionCode) AS [Total Number of Employee]
FROM dbo.employee AS employee_1 INNER JOIN
dbo.Divisions ON employee_1.DivisionCode = dbo.Divisions.SapCode INNER JOIN
dbo.employee_courses ON employee_1.Username = dbo.employee_courses.employeeId INNER JOIN
dbo.courses ON dbo.employee_courses.courseId = dbo.courses.CourseID INNER JOIN
dbo.groups ON dbo.courses.GroupID = dbo.groups.ID
WHERE (dbo.courses.GroupID = 2)
GROUP BY dbo.courses.CourseID, dbo.courses.CourseName, dbo.Divisions.DivisionName, dbo.groups.GroupName
the error message:
column 'dbo.employee.DivisionCode' is invalid in the select list
because it is not contained in either as aggregate function or the
GROUP BY clause.

Issues with a MySQL JOIN statement

i have 5 tables called personal,dailypay,bonuses,iou and loans am trying to write a query that will generate payroll from this table's...my code is
select personal.name as NAME,
(sum(dailypay.pay) + bonuses) - (iou.amount + loans.monthly_due)) as SALARY
from personal
join dailypay on personal.eid = dailypay.eid
left join bonuses on personal.eid = bonuses.eid
left join iou on personal.eid = iou.eid
left join where dailypay.date = 'specified_date'
and bonuses.date_approved = 'specified_date'
and iou.date_approved = 'specified_date'
and loans.date = month(now()
It returns the name and null salary values for staffs that does have records for either bonuses,iou and loans. But i want to sum their dailypay, deduct/add deductions or additions return the values, in the event of no record it should proceed with the summation without any deduction or subtraction.
You missed something when pasting the code, as there is no join for the loans table. Also, you are using the table bonuses as a value, you need a field name also. I added some code for the join and for the field, but used ??? for names that are unknown to me.
When you add or subtract a null value to something else, the result is null, that's why you get null as result when any of the values from the left-joined tables are missing. You can use ifnull(..., 0) to turn a null value into zero.
You need a group by clause, otherwise it would sum up the salary for all persons.
If I get you right, you have several records in the dailypay table for each user, but only one record per user in the other tables? In that case you have the problem that you will be joining the other tables against each row in the dailypay, so if you have 20 payment records for a user, it will count the bonus 20 times. You can use an aggregate like max to get the value only once.
You have put conditions for the left.joined tables in the where clause, but this will turn the joins into inner joins. You should have those conditions in each join clause.
select
personal.name as NAME,
(sum(dailypay.pay) + ifnull(max(bonuses.???), 0)) - (ifnull(max(iou.amount), 0) + ifnull(max(loans.monthly_due), 0)) as SALARY
from
personal
inner join dailypay on personal.eid = dailypay.eid
left join bonuses on personal.eid = bonuses.eid and bonuses.date_approved = 'specified_date'
left join iou on personal.eid = iou.eid and iou.date_approved = 'specified_date'
left join loans on personal.??? = loans.??? and loans.date = month(now())
where
dailypay.date = 'specified_date'
group by
personal.name
There seems to be an extranous left join before the where and a missing closing bracket ) in month(now()
so it should look like:
select personal.name as NAME,
(sum(dailypay.pay) + bonuses) - (iou.amount + loans.monthly_due)) as SALARY
from personal
join dailypay on personal.eid = dailypay.eid
left join bonuses on personal.eid = bonuses.eid
left join iou on personal.eid = iou.eid
where dailypay.date = 'specified_date'
and bonuses.date_approved = 'specified_date'
and iou.date_approved = 'specified_date'
and loans.date = month(now())

How do i deal with this situation for searching records in mysql?

i am developing a PHP/MYSQL search module, where i have to search tables based on many different criteria, i have some 11 tables, and i have used multiple joins to create one single MySQL query and based on WHERE clause i intend to search for specific records, here is the MYSQL Query that i am using.
SELECT
prop.id,
prop.serial,
prop.title,
prop.rating,
prop.addDate,
prop.approve,
prop.status,
prop.user_id as userId,
user_det.email as email,
user_det.name as name,
prop.area_id as areaId,
area.name as areaName,
area.zipCode as zipCode,
area.city_id as cityId,
city.name as cityName,
city.state_id as stateId,
state.name as stateName,
state.country_id as countryId,
country.name as countryName,
prop.subCategory_id as subCategoryId,
subCat.name as subCategoryName,
subCat.category_id as categoryId,
cat.name as categoryName,
prop.transaction_id as transactionId,
trans.name as transactionName,
price.area as landArea,
price.price as priceSqFt,
price.total_price as totalPrice,
features.bedroom,
features.bathroom,
features.balcony,
features.furnished,
features.floorNum,
features.totalFloor
FROM properties prop
LEFT JOIN user_details user_det ON (prop.user_id = user_det.user_id)
LEFT JOIN areas area ON (prop.area_id = area.id)
LEFT JOIN cities city ON (area.city_id = city.id)
LEFT JOIN states state ON (city.state_id = state.id)
LEFT JOIN countries country ON (state.country_id = country.id)
LEFT JOIN subCategories subCat ON (prop.subCategory_id = subCat.id)
LEFT JOIN categories cat ON (subCat.category_id = cat.id)
LEFT JOIN transactions trans ON (prop.transaction_id = trans.id)
LEFT JOIN prop_prices price ON (price.property_id = prop.id)
LEFT JOIN prop_features features ON (features.property_id = prop.id)
although all works well here, i have a situation where i have a table called prop_amenities below are the content of this table.
as the table above have multiple property_id if i query it using JOINS then mostly it will return duplicate records or single record omitting others depending on the type of JOIN i use. so instead i would like to deal it this way.
use the table prop_amenities to only deal with conditions not to return the result.
for example i am searching for a property with amenity id 1,5,9,17 and 24, then it should check if all the records exist in the prop_amenities table, i.e 1,5,9,17 and 24 in this case. and return the appropriate records with all above selected columns.
i am clueless on dealing this situation using MySQL. how do i go on this?
thank you..
You said "check if all the records exist in the prop_amenities table" and that's the key word here.
SELECT ...
FROM properties AS prop
LEFT JOIN ...
WHERE EXISTS (SELECT 1 FROM prop_amenities AS pa WHERE pa.property_id = prop.property_id AND pa.amenity_id = 7);