Access 2010 - optimization a query - ms-access

Can help me please to optimize this query in database (access 2010), this query to work very slowly (if use it in a big table):
SELECT П1.Code, П1.Field, П1.Number, П1.Data, [П1].[Number]-(select П3.Number from [Table] as П3
where П3.Field = П1.Field
and П3.Data = (select Max(Data)
from [Table] as П2
where П2.Field = П1.Field and П1.Data > П2.Data)) AS Difference
FROM [Table] AS П1
ORDER BY П1.Field, П1.Data;
I'm attach a picture: http://s33.postimg.org/otm859xtb/Table_query.png
Link in the database: http://s000.tinyupload.com/?file_id=06711692152703646964

How about...
SELECT t.Code,t.Field,t.Number,t.Data,t.Number-tm.LastNumber AS Difference
FROM [Table] AS t
INNER JOIN (
SELECT t.Field,t.Number AS LastNumber
FROM [Table] AS t
INNER JOIN (
SELECT Field,MAX(Data) AS MaxData
FROM [Table]
GROUP BY Field
) AS tm ON tm.Field=t.Field AND tm.MaxData=t.Data
) AS tm ON tm.Field=t.Field
The sub-selects can give you some issues with formatting in Access, but should work.

PLease try this one, just the same like Kevin ))
SELECT Table.Code, Table.Field, Table.Number, Table.Data, [Table].[Number]-[t1].[number] AS Difference
FROM
(SELECT Table.Code, Table.Field, Table.Number, Table.Data
FROM [Table] INNER JOIN
(SELECT Table.Field, Max(Table.Data) AS MaxOfData
FROM [Table] GROUP BY Table.Field) AS t2 ON (t2.MaxOfData = Table.Data) AND
(Table.Field = t2.Field)) AS t1 INNER JOIN [Table] ON t1.Field = Table.Field;

Related

How to subtract the one row from another MySQL

Given that a table as enclosed
How do I find the difference between Mac and Windows sold each day.
Can someone pls explain the logic
An INNER JOIN would do the job.
SELECT
WindowsTable.Date,
ABS(WindowsTable.Sold - MacTable.Sold) absoluteDifference
FROM
(SELECT
*
FROM producttable
WHERE Products = 'Windows') WindowsTable
INNER JOIN
(
SELECT
*
FROM producttable
WHERE Products = 'Mac' ) MacTable
ON WindowsTable.Date = MacTable.Date;
DEMO HERE
Try reshaping your query using an INNER JOIN on date:
SELECT macs_sales.Date, (MacsSold - WindowsSold) AS sales_difference
FROM
(
SELECT Date, Sold as MacsSold
FROM computer_sales
WHERE Products="Mac"
) macs_sales
INNER JOIN
(
SELECT Date, Sold as WindowsSold
FROM computer_sales
WHERE Products="Windows"
) windows_sales
ON macs_sales.Date = windows_sales.Date

How do I use a function in a view to return only distinct union of rows?

I am trying to do a view to reference on a webpage using RadGrid control. I need to get a subset of all records in my projects table by the last entered Changedate in the Changes table per unique projectid with the Status from the Status table along with the details of the project. The ProjectId & StatusID are in the Changes table as foreign Keys.
This is my view.
CREATE VIEW [dbo].[Project-by_View]
AS
SELECT TOP (100) PERCENT
dbo.Projects.Id,
dbo.Projects.ProjectName,
dbo.Department.Name,
dbo.Designer.FName + ' ' + dbo.Designer.LName AS Designer,
dbo.Changes.ChangeDate,
dbo.Projects.DueDate,
dbo.Projects.Instructions,
dbo.Status.Description
FROM dbo.Projects
INNER JOIN dbo.Department
ON dbo.Department.ID = dbo.Projects.DeptID
INNER JOIN dbo.Designer
ON dbo.Designer.Id = dbo.Projects.DesignerID
INNER JOIN dbo.Changes
ON dbo.Changes.ProjectID = dbo.Projects.ID
INNER JOIN dbo.Status
ON dbo.Changes.StatusID = dbo.Status.Id
WHERE EXIST (SELECT *
FROM GetAllLastChangeDatebyProjectIds(0))
ORDER BY dbo.Projects.ID DESC
GO
and my function
USE [FIDO_DEV]
GO
/****** Object: UserDefinedFunction [dbo].[GetAllLastChangeDatebyProjectIds]
Script Date: 9/14/2015 4:31:22 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author, Geoffrey Stephens>
-- Create date: <Create Date, 09/14/20115>
-- Description: <Description, table of the Last Change Date for each Project>
-- =============================================
ALTER FUNCTION [dbo].[GetAllLastChangeDatebyProjectIds]
(
#ProjectID int
)
RETURNS TABLE
AS
RETURN
(
Select ProjectID, StatusID, ChangeDate from (
Select
ProjectID, StatusID, ChangeDate,
row_number() over(partition by ProjectID order by ChangeDate desc) as rn
from
Changes
) t
where t.rn = 1)
GO
The function works and the View work separately, but in conjunction I still get the full data set returned.
This chunk looks suspicious:
WHERE EXIST (SELECT *
FROM GetAllLastChangeDatebyProjectIds(0))
Should it not look more like:
WHERE EXIST (SELECT *
FROM GetAllLastChangeDatebyProjectIds(Projects.Id))
I haven't looked any deeper, that just jumped out at me.
Try something like this (reformatted to my preferred style)
SELECT Projects.Id,
dbo.Projects.ProjectName,
dbo.Department.Name,
dbo.Designer.FName + ' ' + dbo.Designer.LName AS Designer,
dbo.Changes.ChangeDate,
dbo.Projects.DueDate,
dbo.Projects.Instructions,
dbo.Status.Description
FROM ( SELECT ProjectID,
StatusID,
ChangeDate
FROM ( FROM ProjectID,
StatusID,
ChangeDate,
row_number() OVER (PARTITION BY ProjectID ORDER BY ChangeDate DESC) as rn
FROM Changes) t
WHERE t.rn = 1)) AS Selection
INNER JOIN dbo.Projects
ON dbo.Projects.ID = Selection.ProjectID
INNER JOIN dbo.Designer
ON dbo.Designer.Id = dbo.Projects.DesignerID
INNER JOIN dbo.Department
ON dbo.Department.ID = dbo.Projects.DeptID
INNER JOIN dbo.Changes
ON dbo.Changes.ProjectID = dbo.Projects.ID
INNER JOIN dbo.Status
ON dbo.Changes.StatusID = dbo.Status.Id
WHERE Selection.StatusID = dbo.Changes.StatusID
ORDER BY dbo.Projects.ID DESC
I reordered the Selects, so that I start with the Distinct project.ID and then do the joins. Then did the where on the Status.ID to get the latest distinct record set.
Select TOP 100 PERCENT Projects.Id, dbo.Projects.ProjectName, dbo.Department.Name, dbo.Designer.FName + ' ' + dbo.Designer.LName AS Designer, dbo.Changes.ChangeDate, dbo.Projects.DueDate, dbo.Projects.Instructions, dbo.Status.Description
From GetAllLastChangeDatebyProjectIds(0) INNER JOIN
dbo.Projects ON dbo.Projects.ID = dbo.GetAllLastChangeDatebyProjectIds.ProjectID INNER JOIN
dbo.Designer ON dbo.Designer.Id = dbo.Projects.DesignerID INNER JOIN
dbo.Department ON dbo.Department.ID = dbo.Projects.DeptID INNER JOIN
dbo.Changes ON dbo.Changes.ProjectID = dbo.Projects.ID INNER JOIN
dbo.Status ON dbo.Changes.StatusID = dbo.Status.Id
Where dbo.GetAllLastChangeDatebyProjectIds.StatusID = dbo.Changes.StatusID
ORDER BY dbo.Projects.ID DESC

MySQL Query is slow (Joins/counts)

I have this query:
SELECT `assemblies`.`id`,
`assemblies`.`type`,
`assemblies`.`champion`,
`assemblies`.`name`,
`assemblies`.`author`,
`assemblies`.`githublastmod`,
( assemblies.forum IS NOT NULL ) AS forumExists,
Count(votes.id) AS votesCount,
Count(install_clicks.id) AS installCount,
Count(github_clicks.id) AS githubCount,
Count(forum_clicks.id) AS forumCount
FROM `assemblies`
INNER JOIN `votes`
ON `votes`.`assembly` = `assemblies`.`id`
INNER JOIN `install_clicks`
ON `install_clicks`.`assembly` = `assemblies`.`id`
INNER JOIN `github_clicks`
ON `github_clicks`.`assembly` = `assemblies`.`id`
INNER JOIN `forum_clicks`
ON `forum_clicks`.`assembly` = `assemblies`.`id`
WHERE `assemblies`.`type` = 'utility'
AND Unix_timestamp(Date(assemblies.githublastmod)) > '1419536536'
GROUP BY `assemblies`.`id`
ORDER BY `votescount` DESC,
`githublastmod` DESC
For some reason this query is very slow, I'm using the database engine MyISAM. I hope someone can help me out here :)
Explain command:
I believe this is a case where making the subqueries for the counts will make it run a lot faster (and the values will be correct).
The problem with the original query is the explosion of the number of intermediate rows: For each 'assembly', there were n1 votes, n2 installs, etc. That led to n1*n2*... rows per assembly.
SELECT `assemblies`.`id`, `assemblies`.`type`, `assemblies`.`champion`,
`assemblies`.`name`, `assemblies`.`author`, `assemblies`.`githublastmod`,
( assemblies.forum IS NOT NULL ) AS forumExists,
( SELECT Count(*)
FROM votes
WHERE `assembly` = `assemblies`.`id`
) AS votesCount,
( SELECT Count(*)
FROM install_clicks
WHERE `assembly` = `assemblies`.`id`
) AS installCount,
( SELECT Count(*)
FROM github_clicks
WHERE `assembly` = `assemblies`.`id`
) AS githubCount,
( SELECT Count(*)
FROM forum_clicks.id
WHERE `assembly` = `assemblies`.`id`
) AS forumCount
FROM `assemblies`
WHERE `assemblies`.`type` = 'utility'
AND Unix_timestamp(Date(assemblies.githublastmod)) > '1419536536'
ORDER BY `votescount` DESC, `githublastmod` DESC
Each secondary table needs an INDEX starting with assembly.
Your problem should be fixed using the right indices:
CREATE INDEX index_name_1 ON `votes`(`assembly`);
CREATE INDEX index_name_2 ON `install_clicks`(`assembly`);
CREATE INDEX index_name_3 ON `github_clicks`(`assembly`);
CREATE INDEX index_name_4 ON `forum_clicks`(`assembly`);
Try your query again after creating these indices and it should be quite faster.

MySQL query error 1064 (syntax error)

I'm trying to make the following query work but it seems to contain an error that I can't find. The query in question is:
select
A.*,
SD.*
from
(
( select
V71.Sollevamento_idAttrezzatura,
V71.Num_id_ON,
V71.Affidato_INAIL,
V71.Esito_Verifica,
V71.Prima_Verifica,
V71.Sospensione,
V71.Data_Verbale,
V71.Scadenza,
CO.Nome,
CO.Cognome,
CO.CF,
V71.Costo,
V71.Sconto as ScontoVerbale,
V71.Maggiorazione as MaggiorazioneVerbale,
V71.Indirizzo,
V71.Comune,
V71.Cap,
V71.Provincia,
V71.Regione
from
Verbale_Art71 as V71
join Collaboratore as CO
on V71.Codice_Tecnico = CO.Codice_Collaboratore
where
V71.Data_Verbale >= '2014-01-01'
and V71.Data_Verbale <= '2014-12-31' ) as VC
join
( select
S.Natura,
S.Anno_Immatricolazione,
S.Codice_Attribuzione_Matricola,
S.Provincia_Immatricolazione,
S.Numero_Matricola,
S.idSpecifica,
S.N_Panieri_Idroestrattori,
S.Modello,
S.Numero_Fabbrica,
S.Anno_Costruzione,
S.Sconto as ScontoAttr,
S.Maggiorazione as MaggiorazioneAttr,
P71.Tipo_Attr,
S.Sede,
S.idAttrezzatura
from
Sollevamento as S
join Periodicita_Art71 as P71
on S.idPeriodicita = P71.idPeriodicita ) as SP
on VC.Sollevamento_idAttrezzatura = SP.idAttrezzatura
) as A
join
( select
D.Ragione_Sociale,
D.Indirizzo,
D.Cap,
D.Comune,
D.Provincia,
D.Regione,
D.CF as CF_Ditta,
D.P_IVA,
SC.idSede
from
Ditta as D
join Sede as SC
on SC.Ditta = D.idDitta ) as SD
on ATTR71.Sede = SD.idSede
MySQL notifies that the syntax error is near as A join (select D.Ragione_Sociale, D.Indirizzo, D.Cap, D.Comune, D.Provincia
Anyone can help me find it? I've been looking for it since early morning and I'm going nuts. Thank anyone that will help me in advance, Giacomo
You are missing a select clause
select A.*, SD.*
from
(/* You are missing a select * from here */
(
select ..
) as VC
join
Try with
select A.*, SD.*
from
(select * from
(
select V71.Sollevamento_idAttrezzatura, V71.Num_id_ON, V71.Affidato_INAIL, V71.Esito_Verifica, V71.Prima_Verifica, V71.Sospensione, V71.Data_Verbale, V71.Scadenza, CO.Nome, CO.Cognome, CO.CF, V71.Costo, V71.Sconto as ScontoVerbale, V71.Maggiorazione as MaggiorazioneVerbale, V71.Indirizzo, V71.Comune, V71.Cap, V71.Provincia, V71.Regione
from Verbale_Art71 as V71
join
Collaboratore as CO
on V71.Codice_Tecnico = CO.Codice_Collaboratore
where V71.Data_Verbale >= '2014-01-01' and V71.Data_Verbale <= '2014-12-31'
) as VC
join
(
select S.Natura, S.Anno_Immatricolazione, S.Codice_Attribuzione_Matricola, S.Provincia_Immatricolazione, S.Numero_Matricola, S.idSpecifica, S.N_Panieri_Idroestrattori, S.Modello, S.Numero_Fabbrica, S.Anno_Costruzione, S.Sconto as ScontoAttr, S.Maggiorazione as MaggiorazioneAttr, P71.Tipo_Attr, S.Sede, S.idAttrezzatura
from Sollevamento as S
join
Periodicita_Art71 as P71
on S.idPeriodicita = P71.idPeriodicita
) as SP
on VC.Sollevamento_idAttrezzatura = SP.idAttrezzatura
) as A
join
(
select D.Ragione_Sociale, D.Indirizzo, D.Cap, D.Comune, D.Provincia, D.Regione, D.CF as CF_Ditta, D.P_IVA, SC.idSede
from Ditta as D
join Sede as SC
on SC.Ditta = D.idDitta
) as SD
on ATTR71.Sede = SD.idSede
Your final alias
on ATTR71.Sede = SD.idSede
should be
on A.Sede = SD.idSede
You can see it easily once the formatting / readability is better. The "A" was the alias result of the first JOINs using the ATTR71 alias table... The last join was only to the "A" alias and not the ATTR71 table.

Troubles with nested queries

I have this query which works perfectly:
SELECT *
FROM Customer
WHERE SacCode IN
(
SELECT SacCode
FROM SacCode
WHERE ResellerCorporateID = 392
ORDER BY SacCode
)
AND CustomerID IN
(
SELECT CxID
FROM CustAppointments
WHERE AppRoomID IN
(
SELECT AppRoomID
FROM ClinicRooms
WHERE ClinID IN
(
SELECT ClinID
FROM AppClinics
WHERE ClinDate >='20090101'
AND ClinDate <='20091119'
)
)
)
However, I need to see the value of ClinDate (inside the last nested query)...
How do I do it?
Thanks.
I'd rewrite the query using joins. Then, you can access any data from any of the joined tables.
For example, you could rewrite your query like this:
SELECT c.*, ac.ClinDate
FROM Customer c
JOIN SacCode sc ON sc.SacCode = c.SacCode
JOIN CustAppointments ca ON ca.CustomerID = c.CustomerID
JOIN ClinicRooms cr ON cr.AppRoomID = ca.AppRoomID
JOIN AppClinic ac ON ac.ClinID = cr.ClinID
WHERE ac.ClinDate >='20090101'
AND ac.ClinDate <='20091119'
AND sc.ResellerCorporateID = 392
Think I'd use derived table in the FROM statement rather than 3 deep nested query, will allow you to access values and will look a LOT better.
You'll need to copy the subselects to the FROM clause or rewrite the query using JOINs.
it should look something like this:
SELECT c.*, a.ClinDate
FROM Customer c
inner join CustAppointments ca
inner join ClinicRooms cr
inner join AppClinics a
where c.SacCode IN
(
SELECT SacCode
FROM SacCode
WHERE ResellerCorporateID = 392
ORDER BY SacCode
)
and c.CustomerID = ca.CxID
and ca.AppRoomID = cr.AppRoomID
and cr.ClinID = a.ClinID
and a.ClinDate >='20090101'
and a.ClinDate <='20091119'