Transforming Results from Rows into Columns - mysql

I have a data set that contains both common and unique values, which I am attempting to return in a useable format to allow further analyse/work to be taken based on said results.
The desired result would be to have a script that would recognise the common values such as mpan/serial_number/read_at so as to only return a single row, but also to recognise the unique values those being the read_at and identifier.
Currently my script returns a unique row based on the identifier and the value, but I would like to be able to return a unique row for the read_at date for as many identifiers and values as are held. In most cases there are only two identifiers and values, but there could be as many as five.
The issue I have is that when I try to make distinct work, it will only then return the first found result, where I am expecting a pair of results at minimum. I am also unclear as to how I could stop getting a new row and instead create the result as an additional column?
My base script which pulls everything is as below, I have tried a few variances on this, but think this would likely be the best place to start from with regards to any help you may be able to offer?
SELECT *
FROM consumer.stg_d0010_v2_026_027
/*LEFT JOIN consumer.stg_d0010_v2_026_028_029
ON consumer.stg_d0010_v2_026_028_029.file_identifier = consumer.stg_d0010_v2_026_027.file_identifier
AND consumer.stg_d0010_v2_026_028_029.mpan = consumer.stg_d0010_v2_026_027.mpan*/
LEFT JOIN consumer.stg_d0010_v2_026_028_030_032
ON consumer.stg_d0010_v2_026_028_030_032.file_identifier = consumer.stg_d0010_v2_026_027.file_identifier
AND consumer.stg_d0010_v2_026_028_030_032.mpan = consumer.stg_d0010_v2_026_027.mpan
LEFT JOIN consumer.stg_d0010_v2_026_028_030_033
ON consumer.stg_d0010_v2_026_028_030_033.file_identifier = consumer.stg_d0010_v2_026_027.file_identifier
AND consumer.stg_d0010_v2_026_028_030_033.mpan = consumer.stg_d0010_v2_026_027.mpan
where consumer.stg_d0010_v2_026_028_030_032.read_At > '2022-10-01'
and consumer.stg_d0010_v2_026_027.mpan in (
)
Example dataset in image below.
enter image description here
And desired outcome
enter image description here
The issue I have is that when I try to make distinct work, it will only then return the first found result, where I am expecting a pair of results at minimum. I am also unclear as to how I could stop getting a new row and instead create the result as an additional column?

Related

Socrata API - How to replace empty data fields from query as empty strings in results array

I'm using the "phpsoda" library and trying to query the city of Seattle's permits dataset through the Socrata API (SODA). Data: https://data.seattle.gov/Permitting/Land-Use-Permits/ht3q-kdvx
They have several columns such as the ones I'm selecting below, but in the "AppliedDate" and "IssuedDatae" columns, there may or may not be data in that column.
So when I try to look at the array and arrange this into an HTML table, I'm getting some arrays (rows) that have fewer elements (columns) than other rows. This turns out to make it difficult to display since I don't know which columns are missing in the array (row).
I'm wondering if when I make the query, that those empty fields will look they seem in the visualized table on their site or when I export a CSV. Those columns in the query will return into the array element an empty string ("") instead so my rows and columns will come out all filled with values.
$soql->select("PermitNum", "AppliedDate", "IssuedDate", "Description", "OriginalAddress1")
->where("PermitClass = 'Multifamily' OR PermitClass = 'Commercial')
->limit(20);
$results = $ds->getDataset($soql);
Data would look something like...
print_r($results);
Array[0] -> [Description]=>"XXXXXXX", [PermitNum]=>"123456"
Array[1] -> [Description]=>"XXXXXXX", [PermitNum]=>"234567", [AppliedDate]=>"XX/XX/XXXX"
So the first row is missing the "AppliedDate" column just because it's not in the data.
Will I need to just go through this manually in the results array using a loop and checking column names and inserting an empty string if the loop doesn't find a column?
Following my own advice, I was able to just check for each row key if a specific key was missing (array_key_exists function), then I'd fill it in with "" if it returned false.
This seemed to work.
I have same problem. Socrata API will skip empty field or null value. Means, if field is null or empty, the result will not show field-name:'', instead, the result will just missing this, that cause your shorter row.
This is annoying bug, I have to fix it by my own. If I found it missing field, I will have to add field-name:'' to the result json, that will fix your shorter row problem. Make equal length row.

Searching ALL ROWS in a Group using IIF Expression

I am working on a report that displays patient names (as groups with drilldowns) and several fields related to their visits. I have created a column in the report to display whether or not a specific value appears in the 'LocationID' column. The expression I used is
=IIF(Fields!LocationID.Value="WELL","Y","N")
I thought this was working great, it displays Y or N next to each name to let me know if 'WELL' was in their 'LocationID'. I checked several to ensure that this was going to work and discovered that there was a LocationID code of 'WHS' and since I have the rows ordered by Name and LocationID if there was a WHS visit it shows up at the top of the group and my expression is only seeing this top item. How can this expression be written differently so that it searches the entire result of each group? Depending on the date range a patient may have one visit or they may have ten. I need to check all visits that are returned. Perhaps there is a better method. Thanks in advance.
I agree with jimmy8ball that the easiest way to solve most issues like this is to push some logic back into the SQL layer.
However, if you really want to do this via SSRS functionality, then you could implement a substring search against a lookupset. Assuming you have a patient id in your dataset that is unique for each patient (I hope your group isn't on the name) then...
=Iif(InStr(Join(Lookupset(Fields!patientid.Value, Fields!patientid.Value, Fields!LocationsID.Value, "dataset"), ","), "WELL") > 0, "Y", "N")
Which says, "Search through the dataset for all rows related to my patientid, join every location into a comma deliminated string, search the string for the text "WELL" and return "Y" if it's found.
Obviously if you have locations in your dataset like "WELLY", these will become false positives and you'll have to implement some more nested logic. Try appending a value (perhaps !) to the lookupset return field so that you can search for "WELL!" or some other terminator character.

How to remove non-numeric characters from MySQL cells

I have a table with ~200,000 rows. There are three different phone number columns and the data in them is not all formatted the same. I'd like to remove any value that is not a number and update every cell.
For instance, (412)641-5892 becomes 4126415892.
I found this STRIP_NON_DIGIT() function here. I can use that in my SQL queries and it works properly, but it takes a minute to return a result. I'd like to run a mass UPDATE across the entire table, but not sure what the syntax is for that.
Something like this is what I'm going for.
UPDATE leads
SET phone = STRIP_NON_DIGIT(phone),
mobile_phone = STRIP_NON_DIGIT(mobile_phone),
home_phone = STRIP_NON_DIGIT(home_phone)
Turns out the answer was the pseudo code that I wrote!

Remove query string pairs until a result is returned

Lets say I have a search form on my site which generates a query string to filter results, eg. mysite/search?field1=value1&field2=value2&field3=value3
The user enters the following into the search fields:
Field 1 = Cat
Field 2 = Black
Field 3 = Stray
Given the nature of a query string, all three field values would have to be present in an item being searched, in order for it to be recognised as a match.. right?
Is there a way to either make the '&' an 'OR', so that any matching field will return a result.
Or
Is there a way to match the nearest result? Ie. Remove string pairs until a match is found, or in some way, find the next closest result.
For example. If the user enters 'Cat', 'Black' and 'Stray' and there is an item that includes all three values, it returns that result (standard response). If there isn't an item that includes all three values, let's say there's only an item that has 'Cat' and 'Stray', it recognizes there are no items containing all three values, so it looks for two field value matches instead?
Happy to consider any ideas to prevent "no items found" and at least render something rather than nothing.
It depends on what you're using for filtering but general idea is that after you filter the data you check if it is empty and if it is you remove one filter do the filtering again. Something like this for example:
result = filter(data,filters);
while(!result || filters.length > 0){
filters.pop();
result = filter(data, filters);
}
Not working code, just general idea.

MS Access Query using IFF to compare values

I am trying to build a query which will look at the data in two fields in two different tables and check to see if the data is the same, if it is I want it to return the number of times it is matched, if it isn't I simply want it to return the text saying "No viewings".
I have constructed this query in my access database which has the field from the first table "Property" and the second field I want it to compare the data with, "Viewings". I have build the following expression using the build tool, however I am stuck to make it work since every time I get this error message when trying to run the query: "Your query does not include the specified expression 'Property Viewed' as part of an aggregate function."
totalViewings: IIf([Viewings]![Property Viewed]=[Property]![ID],Count([Viewings]![Property Viewed]=[Property]![ID]),"No Viewings")
Any help how to overcome this error would be very appreciated.
Thanks
I would suggest doing something like this:
1) Assuming this is something you are developing yourself, make sure your data structure is all in order first. Since I dislike relatively code-hostile identifiers, I'd have the tables as so -
Properties - PropertyID (AutoNumber, primary key), HouseNumberOrName, Street, etc.
Viewings - ViewingID (AutoNumber, primary key), PropertyID (Number/Long Integer), ViewingDate, etc.
In the Relationships view, Properties.PropertyID would then be set up to point to Viewings.PropertyID in a one-to-many relation.
2) Your actual query I would then break into two, the first to compile the data and the second to format it for display. The first would go like this, saved as ViewingCounts...
SELECT Properties.PropertyID, Count(Viewings.PropertyID) As ViewingCount
FROM Properties LEFT JOIN Viewings ON Properties.PropertyID = Viewings.PropertyID
GROUP BY Properties.PropertyID;
... and the second like this, saved as ViewingCountsForDisplay:
SELECT Properties.*, IIf(ViewingCount = 0, 'No viewings', ViewingCount) AS Viewings
FROM Properties INNER JOIN ViewingCounts ON Properties.PropertyID = ViewingCounts.PropertyID
ORDER BY Properties.PropertyID;