Tag: SQLNewBlogger

  • Limiting the Max–#SQLNewBlogger

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    I was chatting with someone the other day about MAX() and how it can work within a set of rows, rather than across an entire result set. That’s a good query skill to have, so I mocked up a short demo. This will show the window functions in T-SQL, using the OVER() clause with MAX.

    Let’s build a table and add some data.

    CREATE TABLE counters
    ( countid INT IDENTITY(1,1)
    , countername VARCHAR(20)
    , counteryear INT
    , mycounter INT
    )
    GO
    INSERT dbo.counters
            ( countername
            , counteryear
            , mycounter
            )
        VALUES
            ( 'Test1', 2012, 1 ),
            ( 'Test1', 2013, 2 ),
            ( 'Test1', 2014, 3 ),
            ( 'Test1', 2015, 4 ),
            ( 'Test1', 2016, 5 ),
            ( 'Test1', 2017, 6 )
    GO

    If I now query, I will just use and ORDER BY clause in the OVER() clause. This will order all the rows from the result set by the year, and then apply a MAX to them.

    SELECT
        countid,
        countername,
        counteryear,
        mycounter,
        sumofallvalues = SUM(mycounter) OVER (ORDER BY counteryear),
        maxcounter = MAX(mycounter) OVER (ORDER BY counteryear)
    FROM dbo.counters
    ORDER BY
        countername,
        counteryear;
    

    The partial results are shown below. The important parts are the year and the sum/max values.
    2017-04-18 06_47_36-SQLQuery3.sql - (local)_SQL2016.NBA (PLATO_Steve (71))_ - Microsoft SQL Server M

    We see here that the counter increases by one until the last row. This is the data set, the year and counter increment. The max should be six, but it’s not six until the last row. Why?

    The answer comes from the framing of the rows. The OVER() clause, by default use a range of unbounded preceeding and current row as it’s set of values. In this case, with an order by on the counteryear, this means that when the query engine processes the first row, the entire set of values in the window is just the row with 2012. The next row has two rows, with unbounded preceeding being 2012 and the current row of 2013. This means for each set of rows, the range consists of previous values. I’ll show here what the counteryear values are for each row and the result of the max:

    • 2012 uses the 2012 row only – max 1
    • 2013 uses the 2012 and 2013 rows – max 2
    • 2014 uses the 2012, 2013, and 2014 rows – max 3
    • 2015 uses the 2012, 2013, 2014, 2015 rows – max 4
    • 2016 uses the 2012, 2013, 2014, 2015, 2016 rows – max 5
    • 2017 uses the 2012, 2013, 2014, 2015, 2016 rows – max 6

    This is a window that moves with the data, and is defined as being from the beginning of the result set to the current row.

    Let’s change things. I’ll add a second set of rows, and we can see here how this might differ.

    INSERT dbo.counters
     ( countername
     , counteryear
     , mycounter
     )
     VALUES
     ( 'Test2', 2012, 1 ),
     ( 'Test2', 2013, 4 ),
     ( 'Test2', 2014, 2 ),
     ( 'Test2', 2015, 8 ),
     ( 'Test2', 2016, 5 ),
     ( 'Test1', 2017, 11 )
     GO

    Now, let’s query again, but we’ll change our window. First, we’ll order by name for the MAX(), since that’s what we want to show. I’ll leave SUM alone. Next, I’ll change the window to be only the previous row and the current row.

    SELECT
     countid,
     countername,
     counteryear,
     mycounter,
     sumofallvalues = SUM(mycounter) OVER (ORDER BY counteryear),
     maxcounter = MAX(mycounter) OVER (PARTITION BY countername
     ORDER BY counteryear
     ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
     )
     FROM dbo.counters
     ORDER BY
     countername,
     counteryear;

    Now the results are a bit different. My final ORDER BY ensures I have the tests separated. The first one looks similar in the max columns. I’ll explain the SUM in a different post.

    2017-04-18 06_55_24-SQLQuery3.sql - (local)_SQL2016.NBA (PLATO_Steve (71))_ - Microsoft SQL Server M

    The MAX() for test2 is different. Let’s see what happens here. Since my window is a ROWS clause, and it’s set for 1 preceeding and the current row, I get these values.

    Test2, 2012 row

    • Preceeding  – no values
    • Current – 1
    • Max – 1

    Test2, 2013 row

    • Preceeding  – 1 (2012 value)
    • Current – 4
    • Max – 4

    Test2, 2013 row

    • Preceeding  – 4 (2013 row)
    • Current – 2
    • Max – 4

    Test2, 2014 row

    • Preceeding  – 2
    • Current – 8
    • Max – 8

    Test2, 2015 row

    • Preceeding  – 8
    • Current – 5
    • Max – 8

    This shows that MAX  is limited to the frame I’ve applied to the window. The window is the OVER() clause, which in this case is the set of rows with the same counteryear value (the partition).

    Window functions get confusing and are strange, especially if you’ve spent most of your career without them and finding tricks to use COUNT(), SUM(), and other aggregates on subsets of rows. Things get easier in SQL Server 2012+, and you should spend time playing with small sets of data and understanding windows.

    SQLNewBlogger

    This was about a 15-20 exercise, but it was good since I needed to stop and think about how to use and show a window function and the ranges. Good skills practice.

    I’d like to see others explain this with a data set that they find interesting.

    References

    OVER() – https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql

    MAX() – https://docs.microsoft.com/en-us/sql/t-sql/functions/max-transact-sql

  • DevOps Basics– git Cloning Repos

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    This continues my series on git, because I think it’s good to know what the command line is and how to use it.

    Once you have git running, the thing I’ve often wanted to do is go get code from somewhere. Certainly the creation of a repo and new code is something you might do, but often you’ll be looking to get code from somewhere else, so let’s look at how we can do this.

    Find a Repo

    Most of the time I find a repo somewhere in the company or on the Internet. Fro example, I have a simple database structure that I’ve used for demos at Github. This is my ASimpleTalkDB Repo, which is at: https://github.com/way0utwest/ASimpleTalkDB. You can see it here:

    2017-04-06 13_54_32-way0utwest_ASimpleTalkDB_ Demo repo for Presentations

    Off to the right is a “clone” button, which is what we want to do. We want to perform a git clone. If you click the button, a URL is in an edit box. The URL is: https://github.com/way0utwest/ASimpleTalkDB, the same as the repo above.

    Let’s clone this. First, get a folder to store code in. I started with a Documents\Github folder on my various machines. I’ll use that, and as you can see, this is a place I have a number of folders, each one a repo. I don’t have this repo set up yet.

    2017-04-06 13_58_06-C__Users_way0u_Documents_GitHub

    I’ll clone this from the command line. The various tools do this, but now you’ll understand how this works. First, open a command line in this folder and then type “git clone https://github.com/way0utwest/ASimpleTalkDB”. This will clone the code, as shown below:

    2017-04-06 13_59_46-way0utwest_ASimpleTalkDB_ Demo repo for Presentations

    By default, the name of the repo becomes a folder name, with all the code below that. If I look in Explorer, I can see this.

    2017-04-06 13_59_58-C__Users_way0u_Documents_GitHub_ASimpleTalkDB

    However, I can control this. I’ll delete the folder and do this again. That’s the power of a VCS. I don’t need to worry about this code, because I’ll go get it from another repo.

    Once I delete the folder, I’ll re-run the git clone command, but with the name of a folder added to the end.

    2017-04-06 14_01_55-cmd

    These objects, 264 of them, copy to my machine in a few seconds over hotel wi-fi. This is code, just text, and it’s quick. If I change to the folder and check the status, I see it is a real repo:

    2017-04-06 14_03_01-cmd

    Cloning Folders

    What if I have code inside the company, and not in Github, Gitlab, BitBucket, VSTS, etc. Can I clone things? Yep, you can, but don’t use this to get a copy of your own code. That’s what branches are for. We’ll talk branches later, but for now, we can assume you might have a repo in your company.

    For example, let’s assume for a moment that my C:\users\%username%\source\repos folder is on the network. I can clone one of these repos like this:

    2017-04-06 14_08_12-cmd

    Again, this isn’t the way to get a copy of my own code to work on. This is for getting a repo that I want to work on for myself, where I’ll then merge changes back to the original repo on another machine. On my own machine, I’d just use branches.

    2017-04-06 14_08_12-cmd

    This will help you get some code, and I’d encourage you to copy some code down and see how it works. Go get some code from my repo and build a db if you have SQL Source Control (point this to your cloned repo), or grab something from Microsoft and play.

    That’s it for this post. There are lots of places to go. I’ll talk about how to now push your code elsewhere once you’ve changed it in another post as well as how to branch and accomplish a few other things.

    A few resources (more boring, but will help you learn if you want):

    git clone (git)

    Create a Repo (Channel 9)

  • Watch Your DataTypes in Aggregates–#SQLNewBlogger

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    I’ve got a database of NBA statistics with data like this for players. I downloaded a CSV and loaded it into SQL Server.

    2017-03-22 10_32_00-SQLQuery1.sql - (local)_SQL2016.NBA (PLATO_Steve (102))_ - Microsoft SQL Server

    I decided to play with the data a bit and at one point wanted to see who scored the most points for a team and year. So I ran this query:

    SELECT
        year,
        team,
        MAX(pts)
    FROM dbo.player_regular_season
    WHERE
        year = ‘1972’
        AND team = ‘LAL’
    GROUP BY
        year,
        team;

    The result was 705. That’s a decent number of points, and if I weren’t careful, this might seem fine. 1972 was a long time ago, and they didn’t score as many points as they do today in games.

    In fact, if I were putting this in a summary report with lots of data, it might be the case that someone glancing at this would make a poor decision based on the data.

    Why?

    Let’s look at the data.

    2017-03-22 10_46_16-SQLQuery1.sql - (local)_SQL2016.NBA (PLATO_Steve (102))_ - Microsoft SQL Server

    Even a quick glance would let me know this seems funny. There are values of 1575 and 1084 in there, but the MAX() I returned was 705. If I look deeper at the import, I can see why.

    2017-03-22 10_47_25-SQLQuery1.sql - (local)_SQL2016.NBA (PLATO_Steve (102))_ - Microsoft SQL Server

    Anything stand out there? If you look, pts is a varchar, not a numerical value. In the character world, 705 beats 1575. I really need this query:

    2017-03-22 10_48_30-SQLQuery1.sql - (local)_SQL2016.NBA (PLATO_Steve (102))_ - Microsoft SQL Server

    Always be aware of the datatypes you work with and manipulate. Knowing a little bit about the meaning and use of the data can help you spot anomalies like this. As much as I like random test data, I’d also be sure you have some real data cases when you have users check your work. It’s easy for them to miss problems like this without good reference cases.

    Or use good test data that you’ve setup and unit tests.

  • Getting a VHD into Azure with PoSh

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    I thought this would make a nice SQLNewBlogger post, an easy get started one. I used the docs from Microsoft as a guide, so here’s how it went.

    Login to my account. I used Add-AzureRMAccount here to get the login dialog. I’m not repeating this for now, so this is just an interactive test.

    2017-03-23 14_09_25-Sign in to your Microsoft account

    Now I tried to create a storage account, but I hadn’t assigned a subscription. I didn’t think I needed to  since I only have one,but hey, I guess I do.

    2017-03-23 14_11_36-cmd - powershell

    I started typing Select-AzureSubscription, but realized I didn’t know what it was. I can’t remember naming this and under my name in the portal, I didn’t see a place to find it.

    2017-03-23 14_13_22-Getting a VHD into Azure - Open Live Writer

    Ah, under All Resources I see something, so I’ll try this.

    2017-03-23 14_12_26-All resources - Microsoft Azure

    On second thought, under My Permissions, I see it there.

    2017-03-23 14_14_17-My permissions - Microsoft Azure

    Or not

    2017-03-23 14_14_41-cmd - powershell

    Get-AzureSubscription doesn’t quite work.

    2017-03-23 14_17_54-cmd - powershell

    It’s Get-AzureRMSubscription

    2017-03-23 14_19_02-cmd - powershell

    So, why doesn’t my creation of the storage account work? I should really read error messages. The issue is Select-AzureSubscription fails because I need Select-AzureRMSubscription.

    Sometimes the rev’ing of the cloud is hard.

    Actually, maybe neither work.

    2017-03-23 14_22_02-cmd - powershell

    I retreat.

    2017-03-23 14_23_59-cmd - powershell

    I’m still annoyed. “US West” isn’t valid. FFS, Microsoft. Whether I type any of these, just ask me or process them.

    • “US West”
    • “West US”
    • “USWest”
    • “US_West”

    OK, I decided to go exercise for a bit.

    I’m back (30 minutes later), and I try Get-AzureLocation. I can guess some cmdlets. I get a lot of stuff back and see “West US” is valid. I try a few other valid names of regions, but get errors. It’s not that parameter.

    Let’s try a new name.

    2017-03-23 14_30_22-cmd - powershell

    #$%#@#@# engineers and developers. That’s a valid error message? Not, this is a duplicate or something that makes sense. Glad I left.

    Maybe not. At least this is an error that makes sense.

    2017-03-23 14_31_27-cmd - powershell

    Finally. Let’s upload the VHD.

    2017-03-23 14_33_25-{0%} cmd - powershell

    And it’s off.

    2017-03-23 14_33_41-{0%} cmd - powershell

    Hopefully this will work. I haven’t tried this with PoSh before, and it was somewhat frustrating, though it really didn’t take that long.

    SQLNewBlogger

    This was a bit of a live blog. Do something, take a screenshot, write some text. It was a bit of a learning experience.