I have been doing a lot of research and everything I find is using PHP and MySQL. I need to be able to access my ODBC SQL Server (my MRP system) and display a custom query on a webpage for a visual for my plant. I have not been able to find a way to establish a connection to the database nor the correct way to format the query to display data. Any and all recommendations and formatting corrections are greatly appreciated. I am not even sure HTML is the route I need to go. I just need to build a table based on this data with further ability to format using specific string values from the table.
The query is below:
with cte as
(
SELECT DISTINCT
orout.PartNo,
sched.JobNo,
sched.StepNo,
orout.DeptNum AS MachCell,
orout.WorkCntr as Descrip,
agg.sumHours as HrsLeft,
agg.sumManHrs,
agg.minStartDate,
agg.maxEndDate,
sched.Priority,
od.QtyToMake,
isnull(tt2.QtyComplete,0) as QtyComplete,
CASE
WHEN isnull(tt2.QtyComplete,0) = 0 THEN od.QtyToMake
ELSE (od.QtyToMake - tt2.QtyComplete)
END as QtyOpen,
orout.TotActHrs,
orout.TotEstHrs,
emp.EmplCode,
Emp.NewEmplShortName,
emp.WorkCntr,
wc.Descrip as wcDescrip,
CASE
WHEN emp.EmplCode IS NOT null THEN 1
ELSE 0
END AS LoginPriority
FROM Scheduling as sched
LEFT JOIN OrderRouting as orout
ON orout.JobNo = sched.JobNo AND orout.StepNo = sched.StepNo
LEFT JOIN OrderDet as od
ON orout.JobNo = od.JobNo
LEFT JOIN
(
SELECT
JobNo,
online.EmplCode,
EmplCode.NewEmplShortName,
WorkCntr,
StepNo
FROM Online
INNER JOIN EmplCode
ON EmplCode.EmplCode = online.EmplCode
) emp
ON emp.JobNo = orout.JobNo and emp.StepNo = orout.StepNo
LEFT JOIN
(
SELECT
JobNo,
StepNo,
SUM(ManHrs) as sumManHrs,
SUM(Hours) as sumHours,
MIN(StartDate) as minStartDate,
MAX(EndDate) as maxEndDate
FROM
Scheduling
GROUP BY JobNo, StepNo
) agg
ON agg.JobNo = sched.JobNo AND agg.StepNo = sched.StepNo
LEFT JOIN TimeTicketDet as tt
ON tt.JobNo = orout.JobNo and tt.StepNo = orout.StepNo
LEFT JOIN
(
SELECT
JobNo,
StepNo,
SUM(PiecesFinished+PiecesScrapped) as QtyComplete
FROM
TimeTicketDet as tt2
GROUP BY JobNo, StepNo
) tt2
ON tt2.JobNo = orout.JobNo and tt2.StepNo = tt.StepNo
LEFT JOIN WorkCntr as wc
ON emp.WorkCntr = wc.WorkCntr
WHERE
sched.Priority > 0
)
SELECT *
FROM CTE
WHERE
Descrip = 'MACHINE2'
ORDER BY
LoginPriority DESC, Priority DESC, minStartDate
I would suggest looking for an off-the-shelf application that can use a SQL view as a data source. You can then write a view in SQL to return the data you need displaying, then leave the application to handle everything in the UI.
I've not used any in-depth, and I'm not affiliated with any, but the two I've played with in the past are https://www.tableau.com/ and https://powerbi.microsoft.com. Tableau more of a dashboard tool (and maybe a bit pricey), but I think PowerBI is free, but they're just examples of something you can use. Have a look around, but you should be able to find something that you can use.
Related
I am trying to calculate the leaves taken by employee and the addition and deduction in the salary for this month.
I am stuck at this point where I am joining these tables but I am getting error that I can't bound one of the column from table I specified in FROM clause.
Here is my query, If someone can help that'd be appreciated.
SELECT
[EI].[FirstName]+' '+[EI].[LastName] [Employee],
[Addition].[Amount] [AdditionAmount], [AdditionType].[FullName] [AdditionType],
[Deduction].[Amount] [DeductionAmount], [DeductionType].[FullName] [DeductionType],
MONTH([Leave].[ApprovedOn]) AS [Month], Count(*) AS [LeaveTaken]
FROM
[HRM].[tbl_EmployeeSalary] [Salary],
[HRM].[tbl_EmployeeInfo] [EI]
FULL JOIN [HRM].[tbl_EmployeeLeave] [Leave] ON [EI].[ID] = [Leave].[EmpCode]
FULL JOIN [HRM].[tbl_EmployeeSalaryAddition] [Addition] ON [Salary].[ID] = [Addition].[EmpSalaryCode]
FULL JOIN [HRM].[tbl_AdditionType] [AdditionType] ON [AdditionType].[ID] = [Addition].[AdditionTypeCode]
FULL JOIN [HRM].[tbl_EmployeeSalaryDeduction] [Deduction] ON [Salary].[ID] = [Deduction].[EmpSalaryCode]
FULL JOIN [HRM].[tbl_DeductionType] [DeductionType] ON [DeductionType].[ID] = [Deduction].[DeductionTypeCode]
WHERE
MONTH([Leave].[ApprovedOn]) = MONTH(GetDate())
GROUP BY
[EI].[FirstName]+' '+[EI].[LastName],
[Addition].[Amount], [AdditionType].[FullName],
[Deduction].[Amount] , [DeductionType].[FullName],
MONTH([Leave].[ApprovedOn])
I'm pretty much sure there is some sort of syntax issue like the order I am not able to set. I tried searching the issue but can't figure out in my case.
I don't have table structure still this query will remove your syntactical error
SELECT
[EI].[FirstName]+' '+[EI].[LastName] [Employee],
[Addition].[Amount] [AdditionAmount], [AdditionType].[FullName] [AdditionType],
[Deduction].[Amount] [DeductionAmount], [DeductionType].[FullName] [DeductionType],
MONTH([Leave].[ApprovedOn]) AS [Month], Count(*) AS [LeaveTaken]
FROM
[HRM].[tbl_EmployeeInfo] [EI]
FULL JOIN [HRM].[tbl_EmployeeLeave] [Leave]
ON [EI].[ID] = [Leave].[EmpCode],
[HRM].[tbl_EmployeeSalary] [Salary]
FULL JOIN [HRM].[tbl_EmployeeSalaryAddition] [Addition]
ON [Salary].[ID] = [Addition].[EmpSalaryCode]
FULL JOIN [HRM].[tbl_AdditionType] [AdditionType]
ON [AdditionType].[ID] = [Addition].[AdditionTypeCode]
FULL JOIN [HRM].[tbl_EmployeeSalaryDeduction] [Deduction]
ON [Salary].[ID] = [Deduction].[EmpSalaryCode]
FULL JOIN [HRM].[tbl_DeductionType] [DeductionType]
ON [DeductionType].[ID] = [Deduction].[DeductionTypeCode]
WHERE
MONTH([Leave].[ApprovedOn]) = MONTH(GetDate())
GROUP BY
[EI].[FirstName]+' '+[EI].[LastName],
[Addition].[Amount], [AdditionType].[FullName],
[Deduction].[Amount] , [DeductionType].[FullName],
MONTH([Leave].[ApprovedOn])
I am relatively new at SQL so I apologise if this is obvious but I cannot work out how to use the results of the WITH clause query in the where statement of my main query.
My with query pulls the first record for each customer and gives the sale date for that record:
WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT s.*
FROM summary s
WHERE s.rk=1
I need to use the date in the above query as the starting point and pull all records for each customer for their first 12 months i.e. where the sale date is between ed2.saledate AND ed2.saledate+12 months.
My main query is:
SELECT ed.totalamountincvat, ed.saledate, ed.name AS SaleRef,
ed.customer, ed.customername, comp.numberofemployees,
comp.companyuid
FROM exportdocument AS ed INNER JOIN
FilteredAccount AS comp ON ed.customer = comp.accountid
WHERE (ed.statecode = 0) AND
ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
I am sure that I need to add the main query into the WITH clause but I cant work out where. Is anyone able to help please
Does this help?
;WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT ed.totalamountincvat, ed.saledate, ed.name AS SaleRef,
ed.customer, ed.customername, comp.numberofemployees,
comp.companyuid
FROM exportdocument AS ed INNER JOIN
FilteredAccount AS comp ON ed.customer = comp.accountid
OUTER APPLY (SELECT s.* FROM summary s WHERE s.rk=1) ed2
WHERE ed.statecode = 0 AND
ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
and ed.Customer = ed2.Customer
Results of CTE are not cached or stored, so you can't reuse it.
EDIT:
Based upon your requirement that all the records from CTE should be in final result, this is a new query:
;WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT
ed.totalamountincvat,
ed.saledate,
ed.name AS SaleRef,
ed.customer,
ed.customername,
comp.numberofemployees,
comp.companyuid
FROM
summary ed2
left join exportdocument ed
on ed.Customer = ed2.Customer
and ed.statecode = 0
AND ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
INNER JOIN FilteredAccount comp
ON ed.customer = comp.accountid
WHERE
s.rk=1
summary you will be able to use only once. Alternate solution is store summary into temp table and use that as many times as u want.
Something like : Select * into #temp from Summary s where s.rk=1
I have a complex query with multiple joins in it, which runs multiple times in my application. I want to write this query as a function by breaking this query into smaller pieces inside the function. As a newbie, I have limited knowledge on SQL Server.
The following is the query:
SELECT
ts.lable as label,
ts.percentage as rate
FROM
TaxSet ts
JOIN
UserInfo u ON u.userID = ?
AND u.countryID = ts.countryId
AND (ts.stateId IS NULL OR ts.stateId = 0 OR LEN(ts.stateId) < 1)
JOIN
Users us ON u.userID = us.id
JOIN
Users p ON us.parentID = p.id
AND ts.ispID = p.id
JOIN
ProductType pt ON ts.productTypeID = pt.id
WHERE
startDate <= getutcdate()
AND getutcdate() <= endDate
AND pt.identifier = ?
AND ts.id NOT IN (SELECT eu.ispTaxSettingId
FROM ExemptUsers eu
WHERE eu.ExemptUserId = ?)
Now, how can I write a function by breaking this query into smaller ones.
Thanks in advance.
May I ask why you want to split it into functions? I reformatted your code and have put it into a stored procedure for now. My thinking is that you want to pass through a Identifier and UserID which are the parameters of your query.
I have modified the query and removed the Not In statement. This has been replaced by a LEFT JOIN to ExemptUsers on u.id = eu.ExemptUserID and then an addition to the WHERE clause to ensure eu.ExemptUserID is NULL. This is basically a clearer way of saying "If the userID exists in table ExemptUsers do not bring back results for that user".
In addition I have removed the join to Users p as I can't see that this was being used in any way, unless you want to ensure that the user has a parent?
CREATE PROCEDURE wsp_StoredProcName
(#UserID int,
#Identifier int)
AS
BEGIN
SELECT
ts.lable as label,
ts.percentage as rate
FROM
TaxSet ts
INNER JOIN UserInfo u ON u.userID = ts.UserID
AND u.countryID = ts.countryId
INNER JOIN Users us on u.userID = us.id
INNER JOIN ProductType pt on ts.productTypeID = pt.id
LEFT JOIN ExemptUsers eu on u.id = eu.ExemptUserID
WHERE
(
ts.UserID = #UserID
and pt.identifier = #Identifier
and startDate <= getutcdate()
and getutcdate() <= endDate
AND eu.ExemptUserID IS NULL
and
(
ts.stateId is null or ts.stateId = 0 or len(ts.stateId) < 1
)
)
END
After all you select from TaxSet where certain conditions must be met: The date range, the state, a relation to a particular user and its parent, a relation to a particular product type, and the non-existence for a particular exempt user. So use EXISTS and NOT EXISTS throughout your query in order to make it plain to the reader and dbms what you want to achieve. The more straight-forward a query, the easier it often is for the optimizer to deal with it.
select
ts.lable as label,
ts.percentage as rate
from taxset ts
where getutcdate() between ts.startdate and ts.enddate
and (stateid is null or stateid between 0 and 9)
and exists
(
select *
from users u
join userinfo ui on ui.userid = u.id
where u.id = ?
and ui.countryid = ts.countryid
and u.parentid = ts.ispid
)
and exists
(
select *
from producttype pt
where pt.identifier = ?
and pt.id = ts.producttypeid
)
and not exists
(
select *
from exemptusers eu
where eu.exemptuserid = ?
and eu.isptaxsettingid = ts.id
);
As others have mentioned: When splitting a query into smaller parts and execute these separately, it usually becomes slower not faster. This is due to the fact that a dbms is made to do exactly this in the most efficient way internally. Of course sometimes a dbms' optimizer fails to find a good execution plan, though. You may want to look at the execution plan and check whether you find that plan appropriate.
I'm pulling my hair out over a subquery that I'm using to avoid about 100 duplicates (out of about 40k records). The records that are duplicated are showing up because they have 2 dates in h2.datecreated for a valid reason, so I can't just scrub the data.
I'm trying to get only the earliest date to return. The first subquery (that starts with "select distinct address_id", with the MIN) works fine on it's own...no duplicates are returned. So it would seem that the left join (or just plain join...I've tried that too) couldn't possibly see the second h2.datecreated, since it doesn't even show up in the subquery. But when I run the whole query, it's returning 2 values for some ipc.mfgid's, one with the h2.datecreated that I want, and the other one that I don't want.
I know it's got to be something really simple, or something that just isn't possible. It really seems like it should work! This is MSSQL. Thanks!
select distinct ipc.mfgid as IPC, h2.datecreated,
case when ad.Address is null
then ad.buildingname end as Address, cast(trace.name as varchar)
+ '-' + cast(trace.Number as varchar) as ONT,
c.ACCOUNT_Id,
case when h.datecreated is not null then h.datecreated
else h2.datecreated end as Install
from equipmentjoin as ipc
left join historyjoin as h on ipc.id = h.EQUIPMENT_Id
and h.type like 'add'
left join circuitjoin as c on ipc.ADDRESS_Id = c.ADDRESS_Id
and c.GRADE_Code like '%hpna%'
join (select distinct address_id, equipment_id,
min(datecreated) as datecreated, comment
from history where comment like 'MAC: 5%' group by equipment_id, address_id, comment)
as h2 on c.address_id = h2.address_id
left join (select car.id, infport.name, carport.number, car.PCIRCUITGROUP_Id
from circuit as car (NOLOCK)
join port as carport (NOLOCK) on car.id = carport.CIRCUIT_Id
and carport.name like 'lead%'
and car.GRADE_Id = 29
join circuit as inf (NOLOCK) on car.CCIRCUITGROUP_Id = inf.PCIRCUITGROUP_Id
join port as infport (NOLOCK) on inf.id = infport.CIRCUIT_Id
and infport.name like '%olt%' )
as trace on c.ccircuitgroup_id = trace.pcircuitgroup_id
join addressjoin as ad (NOLOCK) on ipc.address_id = ad.id
The typical approach to only getting the lowest row is one of the following. You didn't bother to specify what version of SQL Server you're using, what you want to do with ties, and I have little interest to try to work this into your complex query, so I'll show you an abstract simplification for different versions.
SQL Server 2000
SELECT x.grouping_column, x.min_column, x.other_columns ...
FROM dbo.foo AS x
INNER JOIN
(
SELECT grouping_column, min_column = MIN(min_column)
FROM dbo.foo GROUP BY grouping_column
) AS y
ON x.grouping_column = y.grouping_column
AND x.min_column = y.min_column;
SQL Server 2005+
;WITH x AS
(
SELECT grouping_column, min_column, other_columns,
rn = ROW_NUMBER() OVER (ORDER BY min_column)
FROM dbo.foo
)
SELECT grouping_column, min_column, other_columns
FROM x
WHERE rn = 1;
This subqery:
select distinct address_id, equipment_id,
min(datecreated) as datecreated, comment
from history where comment like 'MAC: 5%' group by equipment_id, address_id, comment
Probably will return multiple rows because the comment is not guaranteed to be the same.
Try this instead:
CROSS APPLY (
SELECT TOP 1 H2.DateCreated, H2.Comment -- H2.Equipment_id wasn't used
FROM History H2
WHERE
H2.Comment LIKE 'MAC: 5%'
AND C.Address_ID = H2.Address_ID
ORDER BY DateCreated
) H2
Switch that to OUTER APPLY in case you want rows that don't have a matching desired history entry.
Using SQL 2005: “Taking too much time to execute”
I want to filter the date, the date should not display in holidays, and I am using three tables with Inner Join
When I run the below query, It taking too much time to execute, because I filter the cardeventdate with three table.
Query
SELECT
PERSONID, CardEventDate tmp_cardevent3
WHERE (CardEventDate NOT IN
(SELECT T_CARDEVENT.CARDEVENTDATE
FROM T_PERSON
INNER JOIN T_CARDEVENT ON T_PERSON.PERSONID = T_CARDEVENT.PERSONID
INNER JOIN DUAL_PRO_II_TAS.dbo.T_WORKINOUTTIME ON T_CARDEVENT.CARDEVENTDAY = DUAL_PRO_II_TAS.dbo.T_WORKINOUTTIME.DAYCODE
AND T_PERSON.TACODE = DUAL_PRO_II_TAS.dbo.T_WORKINOUTTIME.TACODE
WHERE (DUAL_PRO_II_TAS.dbo.T_WORKINOUTTIME.HOLIDAY = 'true')
)
)
ORDER BY PERSONID, CardEventDate DESC
For the above mentioned Query, there is any other way to do date filter.
Expecting alternative queries for my query?
I'm pretty sure that it's not the joined tables that is the problem, but rather the "not in" that makes it slow.
Try to use a join instead:
select m.PERSONID, m.CardEventDate
from T_PERSON p
inner join T_CARDEVENT c on p.PERSONID = c.PERSONID
inner join DUAL_PRO_II_TAS.dbo.T_WORKINOUTTIME w
on c.CARDEVENTDAY = w.DAYCODE
and p.TACODE = w.TACODE
and w.HOLIDAY = 'true'
right join tmp_cardevent3 m on m.CardEventDate = c.CardEventDate
where c.CardEventDate is null
order by m.PERSONID, m.CardEventDate desc
(There is a from clause missing from your query, so I don't know what table you are trying to get the data from.)
Edit:
Put tmp_cardevent3 in the correct place.
Have you created indices on all of the columns that you are using to do the joins? In particular, I'd consider indices on PERSONID in T_CARDEVENT, TACODE in both T_PERSON and T_WORKINOUTTIME, and HOLIDAY in T_WORKINOUTTIME.