Return values for X and Y where X-Y = Max(X-Y) - tsql

(SQL SERVER 2005)
I have a table of multiple products that relate to an ItemCode. I can establish the best saving using the query below (I think) but what I need to include are the RRP and SellingPrice fields for the combination that provides the best saving.
Apologies in advance this is probably a common issue but I can't find a solution that fits.
SELECT ItemCode, MAX(RRP - [SellingPrice]) AS BestSaving
FROM ItemCodePricingDetail
WHERE ([ProductGroup] = N'SHOES') AND ([Stock Flag] = N'Y')
AND (RRP > 0) AND ([SellingPrice] > 0)
GROUP BY ItemCode
Many Thanks

select * from ItemCodePricingDetail
JOIN
(
SELECT ItemCode, MAX(RRP - [SellingPrice]) AS BestSaving
FROM ItemCodePricingDetail
WHERE ([ProductGroup] = N'SHOES') AND ([Stock Flag] = N'Y')
AND (RRP > 0) AND ([SellingPrice] > 0)
GROUP BY ItemCode
) as t1 on ItemCodePricingDetail.ItemCode=t1.ItemCode
and RRP - [SellingPrice]= t1.BestSaving

Related

Can somebody help me translate this into postgresql?

I am very new to SQL and I do not know much about writing code in the different DBMS. I am trying to write a report in our school's MOODLE platform, which uses postgresql, using a configurable report found here. However, the code does not work in postgresql. In particular, how do I rewrite those lines with variable assignments like #prevtime := to make the code work in postgresql?
Here is the complete code from the link.
SELECT
l.id,
l.timecreated,
DATE_FORMAT(FROM_UNIXTIME(l.timecreated),'%d-%m-%Y') AS dTime,
#prevtime := (SELECT MAX(timecreated) FROM mdl_logstore_standard_log
WHERE userid = %%USERID%% AND id < l.id ORDER BY id ASC LIMIT 1) AS prev_time,
IF (l.timecreated - #prevtime < 7200, #delta := #delta + (l.timecreated-#prevtime),0) AS sumtime,
l.timecreated-#prevtime AS delta,
"User" AS TYPE
FROM prefix_logstore_standard_log AS l,
(SELECT #delta := 0) AS s_init
# CHANGE UserID
WHERE l.userid = %%USERID%% AND l.courseid = %%COURSEID%%
%%FILTER_STARTTIME:l.timecreated:>%% %%FILTER_ENDTIME:l.timecreated:<%%
This is supposed to report the time spent by students in courses in MOODLE.
I assume the original query was written for MySQL. You haven't explained what the query actually does, but the #prevtime hack is usually a workaround for missing window functions, so most probably this can be done using lag() in Postgres, something along the lines:
select l.id,
l.timecreated,
to_char(to_timestamp(l.timecreated), 'dd-mm-yyyy') as dtime,
lag(timecreated) over w as prev_time,
l.timecreated - lag(timecreated) over w as delta,
'User' as type,
FROM prefix_logstore_standard_log AS l
window w as (partition by userid order by id)
WHERE l.userid = %%USERID%%
AND l.courseid = %%COURSEID%%

Find duplicates ok, but why delete doesn't work?

I try to clean table from an open-source building database.
First step is to find duplicates, for that I use
SELECT COUNT(*) AS nbr_doublon, type_local, date_mutation, valeur_fonciere, adresse_code_voie, adresse_nom_voie, adresse_suffixe, adresse_numero, type_local, surface_reelle_bati
FROM dvf_2018
WHERE type_local='Dépendance'
GROUP BY type_local, date_mutation, valeur_fonciere, adresse_code_voie, adresse_nom_voie, adresse_suffixe, adresse_numero, type_local, surface_reelle_bati
HAVING COUNT(*) > 1
Ok, duplicates are identified, but what is the best way to conserve only one for any entry ?
Trying
DELETE
FROM dvf_2018 t1
USING dvf_2018 t2
WHERE t1.id > t2.id
AND t1.type_local='Dépendance'
AND t2.type_local='Dépendance'
AND t1.date_mutation = t2.date_mutation
AND t1.valeur_fonciere = t2.valeur_fonciere
AND t1.adresse_code_voie = t2.adresse_code_voie
AND t1.adresse_nom_voie = t2.adresse_nom_voie
AND t1.adresse_suffixe = t2.adresse_suffixe
AND t1.adresse_numero = t2.adresse_numero
AND t1.type_local = t2.type_local
AND t1.surface_reelle_bati = t2.surface_reelle_bati
But deleting 0 row, why ? What is the best way to do ? Thank you

How to create an Update statement from a subquery in TSQL

I need to update all records that match my criteria. But the Sql below is giving this error:
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
-- Set MasterAccountId = NULL where there is no Receivable with equivalent BillingAccountId and TaskAccountId
UPDATE R
SET R.MasterAccountId = NULL
FROM Receivable R
WHERE EXISTS ( SELECT * FROM MasterAccount M
WHERE (ISNULL(M.BillingAccountId, 0) > 0 AND M.BillingAccountId = R.BillingAccountId) OR
(ISNULL(M.TaskAccountId, 0) > 0 AND M.TaskAccountId = R.TaskAccountId))
Basically, I need to update all records that return in that subquery.
Does any one know how to fix it?
Can you give a try on this. This is base from the repond of https://stackoverflow.com/users/40655/robin-day on this link How do I UPDATE from a SELECT in SQL Server?.
UPDATE
R
SET
R.MasterAccountId = NULL
FROM
Receivable R
INNER JOIN
MasterAccount M
ON
(ISNULL(M.BillingAccountId, 0) > 0 AND M.BillingAccountId = R.BillingAccountId) OR
(ISNULL(M.TaskAccountId, 0) > 0 AND M.TaskAccountId = R.TaskAccountId))
I don't think you are getting the said error in posted query May be somewhere else. Again in your EXISTS subquery, instead of saying select * ... it's always better to say WHERE EXISTS ( SELECT 1 FROM MasterAccount M
Also try using the JOIN version of this query instead like
UPDATE R
SET R.MasterAccountId = NULL
FROM Receivable R
JOIN MasterAccount M ON M.BillingAccountId = R.BillingAccountId
OR M.TaskAccountId = R.TaskAccountId
WHERE ISNULL(M.BillingAccountId, 0) > 0
OR ISNULL(M.TaskAccountId, 0) > 0;

PostgreSQL view embedded if-statements

In my database, for stores that have no rating from Reseller Ratings, they still have an entry but have -1.0 instead of a number between 0.0 and 10.0. The following query results in -10.00 showing up in my view for those stores with -1.0. Instead, I would like either nothing or a - showing up in its place, but I'm not very comfortable with implementing embedded if-statements in my view. Here is my current view.
CREATE VIEW myview AS
SELECT co_url_name AS company_url, score_combined AS stella_score, trunc(score*10, 2) AS bizrate_score,
(SELECT trunc("lifetimeRating"*10, 2)) AS resellerRating_score
FROM ss_profile_co AS s LEFT OUTER JOIN "resellerRatings_ratings" AS r
ON s.id = r.company_id
LEFT OUTER JOIN (SELECT * FROM bizrate_bizrate_ratings WHERE score_name = 'Overall rating') AS b
ON s.id = b.fk_co_id
ORDER BY co_url_name ASC;
The line (SELECT trunc("lifetimeRating"*10, 2)) AS resellerRating_score is the one that returns the negative numbers (or, for valid entries, will return a score between 0.00 and 100.00).
Obviously, I could simply remove these entries from the database that result in this, but it's half a learning experience and half out of my hands to do so anyways.
I appreciate the help!
EDIT: Attempted an embedded if but not surprisingly got an error.
IF (SELECT trunc("lifetimeRating"*10, 2)) = -10.00 THEN NULL ELSE (SELECT trunc("lifetimeRating"*10, 2)) AS resellerRating_score
EDIT2: Figured it out. Line in question is as follows:
(SELECT trunc("lifetimeRating"*10, 2) WHERE trunc("lifetimeRating"*10, 2) > 0) AS resellerrating_score
/foreveralone
Could look like this:
CREATE VIEW myview AS
SELECT co_url_name AS company_url
,score_combined AS stella_score
,trunc(score * 10, 2) AS bizrate_score
,CASE WHEN "lifetimeRating" < 0
THEN NULL
ELSE trunc("lifetimeRating" * 10, 2)
END AS resellerRating_score
FROM ss_profile_co s
LEFT JOIN "resellerRatings_ratings" r ON r.company_id = s.id
LEFT JOIN bizrate_bizrate_ratings b ON b.score_name = 'Overall rating'
AND b.fk_co_id = s.id
ORDER BY co_url_name;
Major points
Concerning your core question: the sub-select without a FROM clause serves no purpose. I simplified that and use a CASE statement instead.
I also simplified your LEFT JOIN to bizrate_bizrate_ratings. No sub-select necessary either. I pulled the WHERE clause up into the JOIN condition. Simpler and faster.
I would advise not to use mixed case identifiers, so you never have to use double quotes. (This probably makes #Daniels comment invalid, because lifetimerating != "lifetimeRating"

How to determine the size of a Full-Text Index on SQL Server 2008 R2?

I have a SQL 2008 R2 database with some tables on it having some of those tables a Full-Text Index defined. I'd like to know how to determine the size of the index of a specific table, in order to control and predict it's growth.
Is there a way of doing this?
The catalog view sys.fulltext_index_fragments keeps track of the size of each fragment, regardless of catalog, so you can take the SUM this way. This assumes the limitation of one full-text index per table is going to remain the case. The following query will get you the size of each full-text index in the database, again regardless of catalog, but you could use the WHERE clause if you only care about a specific table.
SELECT
[table] = OBJECT_SCHEMA_NAME(table_id) + '.' + OBJECT_NAME(table_id),
size_in_KB = CONVERT(DECIMAL(12,2), SUM(data_size/1024.0))
FROM sys.fulltext_index_fragments
-- WHERE table_id = OBJECT_ID('dbo.specific_table_name')
GROUP BY table_id;
Also note that if the count of fragments is high you might consider a reorganize.
If you are after a specific Catalogue
Use SSMS
- Clik on [Database] and expand the objects
- Click on [Storage]
- Right Click on {Specific Catalogue}
- Choose Propertie and click.
IN General TAB.. You will find the Catalogue Size = 'nn'
I use something similar to this (which will also calculate the size of XML-indexes, ... if present)
SELECT S.name,
SO.name,
SIT.internal_type_desc,
rows = CASE WHEN GROUPING(SIT.internal_type_desc) = 0 THEN SUM(SP.rows)
END,
TotalSpaceGB = SUM(SAU.total_pages) * 8 / 1048576.0,
UsedSpaceGB = SUM(SAU.used_pages) * 8 / 1048576.0,
UnusedSpaceGB = SUM(SAU.total_pages - SAU.used_pages) * 8 / 1048576.0,
TotalSpaceKB = SUM(SAU.total_pages) * 8,
UsedSpaceKB = SUM(SAU.used_pages) * 8,
UnusedSpaceKB = SUM(SAU.total_pages - SAU.used_pages) * 8
FROM sys.objects SO
INNER JOIN sys.schemas S ON S.schema_id = SO.schema_id
INNER JOIN sys.internal_tables SIT ON SIT.parent_object_id = SO.object_id
INNER JOIN sys.partitions SP ON SP.object_id = SIT.object_id
INNER JOIN sys.allocation_units SAU ON (SAU.type IN (1, 3)
AND SAU.container_id = SP.hobt_id)
OR (SAU.type = 2
AND SAU.container_id = SP.partition_id)
WHERE S.name = 'schema'
--AND SO.name IN ('TableName')
GROUP BY GROUPING SETS(
(S.name,
SO.name,
SIT.internal_type_desc),
(S.name, SO.name), (S.name), ())
ORDER BY S.name,
SO.name,
SIT.internal_type_desc;
This will generally give numbers higher than sys.fulltext_index_fragments, but when combined with the sys.partitions of the table, it will add up to the numbers returned from EXEC sys.sp_spaceused #objname = N'schema.TableName';.
Tested with SQL Server 2016, but documentation says it should be present since 2008.