chaning the view/style of sql xml auto - sql

i have the below peice of code (following on for my earlier question SQL How to list Columns in a Table as a Cursor Statement)
select
(select * from
(select Narrative
from OfficeClientLedger
where ptMatter=$Matter$ and ptTrans = 4)
as Disbursments for xml auto)
Which returns
<OFFICECLIENTLEDGER NARRATIVE="M0604/20 Cwm Taff NHS Trust Medical Records (C)"/><OFFICECLIENTLEDGER NARRATIVE="M0604/210 Dr Purby Medeical Records (C)"/><OFFICECLIENTLEDGER NARRATIVE="M0604.20 Orchid Cellmark tld Fee"/><OFFICECLIENTLEDGER NARRATIVE="M0604/20 Parsons Dowd Psychological Ltd Assessment Fees"/><OFFICECLIENTLEDGER NARRATIVE="M0604/20 Dr R Oretti Drug testing"/><OFFICECLIENTLEDGER NARRATIVE="M0604/20 Correction of MIssposting CQ 013524"/><OFFICECLIENTLEDGER NARRATIVE="M0604/20 Helen Blackler Assessment Fees (P) "/>
However, I need it to bring me a list such as
M0604/20 Cwm Taff NHS Trust Medical
Records (C)
M0604/210 Dr Purby Medeical Records
(C)
M0604.20 Orchid Cellmark tld Fee
M0604/20 Parsons Dowd
M0604/20 Dr R Oretti Drug testing
M0604/20 Correction of MIssposting CQ
013524
M0604/20 Helen Blackler Assessment
Fees (P)
any ideas? thanks

select
(select cast(Narrative as varchar(max))
from OfficeClientLedger
where ptMatter=$Matter$ and ptTrans = 4
as Disbursments for xml path(''), true)

You could use an XSL style sheet to change the format of the XML retrieved from SQL Server.
http://sqlxml.org/faqs.aspx?faq=99

Related

How to format results in Postgres?

I need to show the location of content within a course that lives in a Virtual Learning Environment (VLE) - basically it is a teaching and learning website that is backed by a Postgres database.
I created the following query that returns the raw data. A sample of this is below
WITH RECURSIVE folders AS(
SELECT ccs.pk1, ccs.parent_pk1, ccs.position, ccs.folder_ind, ccs.title
FROM course_contents ccs
INNER JOIN course_main cm ON cm.pk1 = ccs.crsmain_pk1
WHERE cm.course_id = '<COURSE ID>'
and ccs.pk1 = '<INDEX>' -- primary key
UNION ALL
SELECT cc.pk1, cc.parent_pk1, cc.position, cc.folder_ind, cc.title
FROM course_contents cc
JOIN folders ON folders.pk1 = cc.parent_pk1
)
SELECT f.*
FROM folders f
SAMPLE DATA
PK1
PARENT_PK1
POSITION
FOLDER
TITLE
11497702
NULL
0
Y
Assessment
11497708
11497702
0
N
Using the Assessment Tools
11497709
11497702
1
N
Past Exams Papers
11497710
11497702
2
N
Using the Assessment Tools
11497711
11497702
3
N
Past Exams Papers
I would like to display it like the table below. Something to note is that there are multiple levels - files in folders, and folders in folders, etc.
PATH
Assessment - Using the Assessment Tools
Assessment - Past Exams Papers
Assessment - Using the Assessment Tools
Assessment - Past Exams Papers
I've used the following line
SELECT STRING_AGG(f.title,' - ') AS path
FROM folders f
GROUP BY f.parent_pk1
but it displays like
PATH
Assessment
Using the Assessment Tools - Past Exams Papers - Using the Assessment Tools - Past Exams Papers"
Any help would be very much appreciated.
Thanks
Hmmm . . . I think you want something like this rather than aggregation:
select f.*
from (select first_value(f.title) over (order by position) || '-' || first_value(f.title) over (order by position desc)
from folders f
) f
where folder = 'N';
Thanks to Gordon's answer above I have found the answer I was looking for.
I made a few changes to Gordon's code. Please see below. I do need to test this with more data though to see if it fully replicates the content structure.
select f.*
from (select first_value(f.title) over (order by position) || ' > ' ||
f.title
from folders f
where f.folder_ind = 'N'
) f

Select Top Row in a Group By without any numerical aggregation

I am trying to build a Item Table in access. I have item number, mfg name, and product description. I would like my PK to be item number and mfg name. However, I have about 5k areas where the product description is creating duplicates based on a slight variation in the description itself. I would like to just have access create the table by grouping all items based on item number and mfg name and then select the first result.
NOTE: the method I have attempted below uses MIN/MAX. This does NOT have to be the method suggested. Ultimate goal is to select the top row or a single row for each group So if i have 2 part numbers that say 123 and 2 product descriptions for that part number, I just want one of those descriptions to display. It does NOT matter which one.
Example:
Item_Num, MFG_Name, Product_Desc
414001000, AMBU INC., ASCOPE 3,LARGE,5.8/2.8 5EA/BX
414001000, AMBU INC., ASCOPE 3,LARGE,5.8/2.8 5EA/BX
06L21-01, ABBOTT LABORATORIES INC, 07K0040AT HAVAB-M CALB 4ML RX
06L21-01, ABBOTT LABORATORIES INC, ARCHITECT HAVAB-M CALB 4ML RX
Ideally, this is my result:
Item_Num, MFG_Name, Product_Desc
414001000, AMBU INC., ASCOPE 3,LARGE,5.8/2.8 5EA/BX
06L21-01, ABBOTT LABORATORIES INC, 07K0040AT HAVAB-M CALB 4ML RX
Idea so far that I have is to count the length of the description to quantify. Then use min/max to select the one that is desired. My code so far is:
SELECT
x.distributor_item_number,
x.mfg_item_number,
x.mfg_name,
x.distributor_product_description,
min(x.[LENGTH OF DESC])
INTO Product_Table
FROM [Product Table] AS x
INNER JOIN
(SELECT p.distributor_item_number,
max(p.[LENGTH OF DESC]) AS [MAX LENGTH]
FROM [Product Table] AS p
GROUP BY p.distributor_item_number) AS y ON (y.distributor_item_number = x.distributor_item_number) AND (y.[MAX LENGTH] = X.[LENGTH OF DESC])
GROUP BY x.distributor_item_number, x.mfg_item_number, x.mfg_name, x.distributor_product_description;
However, it doesn't seem to be working. I am still having duplicates in the data.
Any help would be wonderful.
I ended up adding a sequencing number in the select statement that would sequence for each group. Then I just selected the first row of each sequence. Code below
SELECT
p1.mfg_item_number,
p1.mfg_name,
p1.distributor_product_description,
Count(*) AS Seq
INTO Clean_Product_Table
FROM Product_Table AS p1
INNER JOIN Product_Table AS p2 ON (p2.mfg_item_number = p1.mfg_item_number)
AND (P2.MFG_NAME = P1.MFG_NAME)
AND (p2.InoSeq <= p1.InoSeq)
GROUP BY p1.mfg_item_number,
p1.mfg_name,
p1.distributor_product_description
HAVING COUNT(*) = 1
ORDER BY 1, 2, 5;

Join on partial column to compare ERP CRM codes

We're integrating our erp and crm. We want to compare lookup codes. The erp has codes in the code table, code_value column. The crm has a lookup table with a delimiter of // in the column. For example, the crm has state with the state abbreviation and // then the state long name. VA// VIRGINIA. It has the country code split with the first 15 characters and a //. I need to do left and right joins on the code_value column and the crm entry column on the characters before the // to find codes that don't match so we can update those to match. How do I join on the characters before the // delimiter? The position will change. There are many other codes to compare but the pattern is the same. The charters before the // delimiter in the crm match the erp. I need something like join on the length of the column before the // characters.
version sql server 2008r
erp
code table
code_value column
united states of america
Equatorial Guinea
VA
VI
crm
lookup table
entry
united states o//f america
Equatorial Guin//ea
VA// VIRGINIA
VI// VIRGIN ISLANDS
SELECT LOOKUP_CODE, CODE_VALUE_KEY, CODE_VALUE, SHORT_DESC, MEDIUM_DESC, LONG_DESC,
FIELDNAME, LOOKUPSUPP, ENTRY, MASTERVALUE, U_ENTRY, recid
FROM Bridge_Test.DBO.CODE_TABLE PW LEFT JOIN GoldMine_test.dbo.LOOKUP GM ON PW.MEDIUM_DESC = GM.ENTRY --need to join on first 15 characters
Just add LEFT() function to the on join part
it will look like this LEFT(GM.ENTRY, 15)
SELECT LOOKUP_CODE, CODE_VALUE_KEY, CODE_VALUE, SHORT_DESC, MEDIUM_DESC, LONG_DESC, FIELDNAME, LOOKUPSUPP, ENTRY, MASTERVALUE, U_ENTRY, recid
FROM Bridge_Test.DBO.CODE_TABLE PW
LEFT JOIN GoldMine_test.dbo.LOOKUP GM
ON LEFT(PW.MEDIUM_DESC, CharIndex('//', GM.ENTRY) -1) = LEFT(GM.ENTRY, CharIndex('//', GM.ENTRY ) -1)

SQL Query Unique Equipment List

Thanks in advance for having a look. I have no idea on how to search for this.
Picture 2 test stations, each with a rack of equipment that must be kept calibrated. The equipment is identified by stationId, eqPartno, and eqLocation. Location instead of serial number so it is unit replaceable.
From 2 tables:
station_events (eventId is auto, recUpdated is auto)
"stationEventId","stationId","stationEvent","recUpdated"
1,"1","databaseCreation",2014-05-14 07:51:25 AM
2,"55","databaseCreation",2014-05-14 07:51:25 AM
3,"1","updateCal",2014-05-14 08:11:26 AM
4,"1","updateCal",2014-05-14 08:11:59 AM
5,"1","updateCal",2014-05-14 08:48:26 AM
equipment (equipmentId is auto, recUpdated is auto, linked by equipmentId)
"equipmentId","stationEventId","eqPartNo","eqLocation","eqCalExpires","eqRecUpdated"
1,1,"eq1","loc1",2000-01-31,2014-05-14 07:53:59 AM
2,1,"eq2","loc2",2000-02-22,2014-05-14 08:05:52 AM
3,3,"eq1","loc1",2014-04-04,2014-05-14 08:13:37 AM
4,4,"eq2","loc2",2014-04-05,2014-05-14 08:14:25 AM
5,5,"eq1","loc1",2014-04-05,2014-05-14 08:47:04 AM
The query is to form a view of station 1 equipment consisting of the latest record for each of the installed units to verify cal.
select e.* from equipment e
inner join station_events se on se.stationEventId=e.stationEventId
where se.stationId='1'
group by eqPartNo,eqLocation
The results look good.
"equipmentId","stationEventId","eqPartNo","eqLocation","eqCalExpires","eqRecUpdated"
5,5,"eq1","loc1",2014-04-05,2014-05-14 08:47:04 AM
4,4,"eq2","loc2",2014-04-05,2014-05-14 08:14:25 AM
Have I just created a lucky hack, or is this correct? I like this because we have calibration history as long as the view is guaranteed to describe all the latest equipment records.
Best Regards,
Jim Shedden
This is lucky one. You may insert an aggregate such MAX into your query
select e.equipmentId,
e.stationEventId,
e.eqPartNo,
e.eqLocation,
e.eqCalExpires,
MAX(e.eqRecUpdated) from equipment e
inner join station_events se on se.stationEventId=e.stationEventId
where se.stationId='1'
group by eqPartNo,eqLocation

Pivot Table from Three Tables without Aggregate

Apologies for my lack of knowledge on this, I've researched here and elsewhere but have hit a brick wall (my brain). I'm trying to display the rates for a villa in a table like this:
SPRING SUMMER FALL WINTER MAX GUESTS
2 Rooms $343 $288 $389 $467 2
3 Rooms $456 $415 $536 $756 4
Whole Villa $809 $789 $906 $1023 6
I assume that PIVOT is the answer to my woes. I'm using SQL Server 2008 on MS Server 2008 R2
The seasons, packages and prices are stored in 3 tables like this:
CONFIGURATIONS
--------------
configurationID
configurationName
maximumGuests
SEASONS
-------
seasonID
seasonName
CONFIGURATIONSEASONRATES
------------------------
seasonID
configurationID
price
I got as far as this based on the examples I've been able to find:
SELECT 'Packages', 'Summer', 'Winter', 'Christmas', 'Tropical'
FROM
(SELECT ACCOMMODATION_configurations.configurationName, price
FROM ACCOMMODATION_configurations INNER JOIN
ACCOMMODATION_configurationSeasonRates ON
ACCOMMODATION_configurations.configurationID = ACCOMMODATION_configurationSeasonRates.configurationID INNER JOIN
ACCOMMODATION_seasons ON ACCOMMODATION_configurationSeasonRates.seasonID = ACCOMMODATION_seasons.seasonID) as somethingNice
PIVOT (sum(price) for ACCOMMODATION_configurations.configurationName IN (['Summer'],['Winter'],['Christmas'],['Tropical'])) as anyThing
But I get an error saying
The column prefix 'ACCOMMODATION_configurations' does not match with a table name or alias used in the query
I then tried replacing SELECT 'Packages' with SELECT ACCOMMODATION_configurations.configurationName but then I am told that:
SELECT ACCOMMODATION_configurations.configurationName cannot be bound
Thanks in advance for any help!
Inside of your PIVOT syntax you need to remove the ACCOMMODATION_configurations. Also remove the single quotes around the values in the FOR and you need to add the Packages column to the inner select.
So the code will be:
-- this select will display the packages and the seasons
SELECT Packages, Summer, Winter, Christmas, Tropical
FROM
(
-- add Packages to this select list
SELECT Packages, ac.configurationName, price
FROM ACCOMMODATION_configurations ac
INNER JOIN ACCOMMODATION_configurationSeasonRates sr
ON ac.configurationID = sr.configurationID
INNER JOIN ACCOMMODATION_seasons s
ON sr.seasonID = s.seasonID
) as somethingNice
PIVOT
(
sum(price)
for configurationName IN ([Summer],[Winter],[Christmas],[Tropical])
) as anyThing
Edit, based on your comment it seems like you might want:
-- this select will display the packages and the seasons
SELECT Packages, Summer, Winter, Christmas, Tropical
FROM
(
SELECT ac.configurationName as Packages, price, seasonName
FROM ACCOMMODATION_configurations ac
INNER JOIN ACCOMMODATION_configurationSeasonRates sr
ON ac.configurationID = sr.configurationID
INNER JOIN ACCOMMODATION_seasons s
ON sr.seasonID = s.seasonID
) as somethingNice
PIVOT
(
sum(price)
for seasonName IN ([Summer],[Winter],[Christmas],[Tropical])
) as anyThing