SELECT-Beispiele (Transact-SQL) - SQL Server (2023)

  • Artikel
  • 11Minuten Lesedauer

Gilt für:SELECT-Beispiele (Transact-SQL) - SQL Server (1)SQL ServerSELECT-Beispiele (Transact-SQL) - SQL Server (2)Azure SQL-DatenbankSELECT-Beispiele (Transact-SQL) - SQL Server (3)Azure SQL Managed Instance

In diesem Thema werden Beispiele für die Verwendung der SELECT-Anweisung bereitgestellt.

A. Verwenden von SELECT zum Abrufen von Zeilen und Spalten

Im folgenden Beispiel werden drei Codebeispiele aufgeführt. Im ersten Codebeispiel werden alle Zeilen (es ist keine WHERE-Klausel angegeben) und alle Spalten (mit *) aus der Product-Tabelle in der AdventureWorks2019-Datenbank zurückgegeben.

USE AdventureWorks2012;GOSELECT *FROM Production.ProductORDER BY Name ASC;-- Alternate way.USE AdventureWorks2012;GOSELECT p.*FROM Production.Product AS pORDER BY Name ASC;GO

In diesem Beispiel werden alle Zeilen (keine WHERE-Klausel angegeben) und nur eine Teilmenge der Spalten (Name, ProductNumber, ListPrice) aus der Product-Tabelle in der AdventureWorks2019-Datenbank zurückgegeben. Außerdem werden Spaltenüberschriften hinzugefügt.

USE AdventureWorks2012;GOSELECT Name, ProductNumber, ListPrice AS PriceFROM Production.Product ORDER BY Name ASC;GO

In diesem Beispiel werden nur die Zeilen für Product zurückgegeben, die über die Produktgruppe R verfügen und für die die Anzahl von Fertigungstagen weniger als 4 beträgt.

USE AdventureWorks2012;GOSELECT Name, ProductNumber, ListPrice AS PriceFROM Production.Product WHERE ProductLine = 'R' AND DaysToManufacture < 4ORDER BY Name ASC;GO

B. Verwenden von SELECT mit Spaltenüberschriften und Berechnungen

In diesen Beispielen werden alle Zeilen aus der Product-Tabelle zurückgegeben. Im ersten Beispiel werden die Gesamtumsatzzahlen und die Rabatte für jedes Produkt zurückgegeben. Im zweiten Beispiel werden die gesamten Einnahmen für jedes Produkt berechnet.

(Video) SELECT in T-SQL

USE AdventureWorks2012;GOSELECT p.Name AS ProductName, NonDiscountSales = (OrderQty * UnitPrice),Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)FROM Production.Product AS p INNER JOIN Sales.SalesOrderDetail AS sodON p.ProductID = sod.ProductID ORDER BY ProductName DESC;GO

Diese Abfrage berechnet die Einnahmen für jedes Produkt in dem jeweiligen Kaufauftrag.

USE AdventureWorks2012;GOSELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)), ' for ',p.Name AS ProductName FROM Production.Product AS p INNER JOIN Sales.SalesOrderDetail AS sodON p.ProductID = sod.ProductID ORDER BY ProductName ASC;GO

C. Verwenden von DISTINCT mit SELECT

Im folgenden Beispiel wird DISTINCT verwendet, um das Abrufen von doppelten Titeln zu verhindern.

USE AdventureWorks2012;GOSELECT DISTINCT JobTitleFROM HumanResources.EmployeeORDER BY JobTitle;GO

D: Erstellen von Tabellen mit SELECT INTO

Im ersten Beispiel wird eine temporäre Tabelle namens #Bicycles in tempdb erstellt.

USE tempdb;GOIF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULLDROP TABLE #Bicycles;GOSELECT * INTO #BicyclesFROM AdventureWorks2012.Production.ProductWHERE ProductNumber LIKE 'BK%';GO

In diesem zweiten Beispiel wird eine dauerhafte Tabelle namens NewProducts erstellt.

USE AdventureWorks2012;GOIF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL DROP TABLE dbo.NewProducts;GOALTER DATABASE AdventureWorks2012 SET RECOVERY BULK_LOGGED;GOSELECT * INTO dbo.NewProductsFROM Production.ProductWHERE ListPrice > $25 AND ListPrice < $100;GOALTER DATABASE AdventureWorks2012 SET RECOVERY FULL;GO

Eine korrelierte Unterabfrage ist eine Abfrage, die von der äußeren Abfrage abhängig ist. Die Abfrage kann wiederholt ausgeführt werden, und zwar einmal für jede Zeile, die von der äußeren Abfrage ausgewählt wird.

Im ersten Beispiel werden Abfragen gezeigt, die semantisch ähnlich sind, um den Unterschied zwischen der Verwendung des EXISTS-Schlüsselworts und des IN-Schlüsselworts zu veranschaulichen. In beiden Fällen handelt es sich um eine gültige Unterabfrage, die eine Instanz von jedem Produktnamen abruft, für den als Produktmodell ein langärmeliges Logo-T-Shirt angegeben ist und für den die ProductModelID-Nummern in den Product- und ProductModel-Tabellen übereinstimmen.

USE AdventureWorks2012;GOSELECT DISTINCT NameFROM Production.Product AS p WHERE EXISTS (SELECT * FROM Production.ProductModel AS pm WHERE p.ProductModelID = pm.ProductModelID AND pm.Name LIKE 'Long-Sleeve Logo Jersey%');GO-- ORUSE AdventureWorks2012;GOSELECT DISTINCT NameFROM Production.ProductWHERE ProductModelID IN (SELECT ProductModelID FROM Production.ProductModel AS pm WHERE p.ProductModelID = pm.ProductModelID AND Name LIKE 'Long-Sleeve Logo Jersey%');GO

Im nächsten Beispiel wird IN verwendet und eine Instanz des Vor- und Nachnamens der einzelnen Mitarbeiter abgerufen, für die der Bonus in der Tabelle SalesPerson5000.00 beträgt und für die die Mitarbeiter-IDs in den Tabellen Employee und SalesPerson übereinstimmen.

USE AdventureWorks2012;GOSELECT DISTINCT p.LastName, p.FirstName FROM Person.Person AS p JOIN HumanResources.Employee AS e ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN (SELECT Bonus FROM Sales.SalesPerson AS sp WHERE e.BusinessEntityID = sp.BusinessEntityID);GO

Die vorherige Unterabfrage in dieser Anweisung kann nicht unabhängig von der äußeren Abfrage ausgewertet werden. Sie benötigt einen Wert für Employee.EmployeeID, wobei sich dieser Wert ändert, wenn die SQL Server-Datenbank-Engine unterschiedliche Zeilen in Employee untersucht.

(Video) Let's Learn SQL! Lesson 128: Creating a Queue Table

Eine abhängige Unterabfrage kann auch in der HAVING-Klausel einer äußeren Abfrage verwendet werden. Mit diesem Beispiel können Sie die Produktmodelle ermitteln, bei denen der maximale Listenpreis mehr als doppelt so hoch ist wie der Durchschnittpreis für das Modell.

USE AdventureWorks2012;GOSELECT p1.ProductModelIDFROM Production.Product AS p1GROUP BY p1.ProductModelIDHAVING MAX(p1.ListPrice) >= (SELECT AVG(p2.ListPrice) * 2 FROM Production.Product AS p2 WHERE p1.ProductModelID = p2.ProductModelID);GO

In diesem Beispiel werden zwei abhängige Unterabfragen verwendet, um die Namen von Mitarbeitern zu finden, die ein bestimmtes Produkt verkauft haben.

USE AdventureWorks2012;GOSELECT DISTINCT pp.LastName, pp.FirstName FROM Person.Person pp JOIN HumanResources.Employee eON e.BusinessEntityID = pp.BusinessEntityID WHERE pp.BusinessEntityID IN (SELECT SalesPersonID FROM Sales.SalesOrderHeaderWHERE SalesOrderID IN (SELECT SalesOrderID FROM Sales.SalesOrderDetailWHERE ProductID IN (SELECT ProductID FROM Production.Product p WHERE ProductNumber = 'BK-M68B-42')));GO

F. Verwenden von GROUP BY

Im folgenden Beispiel wird die jeweilige Summe der einzelnen Kaufaufträge in der Datenbank ermittelt.

USE AdventureWorks2012;GOSELECT SalesOrderID, SUM(LineTotal) AS SubTotalFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDORDER BY SalesOrderID;GO

Wegen der GROUP BY-Klausel wird für jede Bestellung nur eine Zeile zurückgegeben, die die Summe aller Kaufaufträge enthält.

G. Verwenden von GROUP BY mit mehreren Gruppen

Dieses Beispiel ermittelt den Durchschnittspreis und die Summe der Jahr-bis-heute-Verkäufe, die nach Produkt-ID und Sonderangebots-ID gruppiert sind:

USE AdventureWorks2012;GOSELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS [Average Price], SUM(LineTotal) AS SubTotalFROM Sales.SalesOrderDetailGROUP BY ProductID, SpecialOfferIDORDER BY ProductID;GO

H. Verwenden von GROUP BY und WHERE

In diesem Beispiel werden die Ergebnisse in Gruppen zusammengefasst, nachdem nur die Zeilen mit Listenpreisen von mehr als $1000 abgerufen wurden.

USE AdventureWorks2012;GOSELECT ProductModelID, AVG(ListPrice) AS [Average List Price]FROM Production.ProductWHERE ListPrice > $1000GROUP BY ProductModelIDORDER BY ProductModelID;GO

I. Verwenden von GROUP BY mit einem Ausdruck

Im folgenden Beispiel wird nach einem Ausdruck gruppiert. Sie können nach einem Ausdruck gruppieren, wenn dieser keine Aggregatfunktionen enthält.

USE AdventureWorks2012;GOSELECT AVG(OrderQty) AS [Average Quantity], NonDiscountSales = (OrderQty * UnitPrice)FROM Sales.SalesOrderDetailGROUP BY (OrderQty * UnitPrice)ORDER BY (OrderQty * UnitPrice) DESC;GO

J. Verwenden von GROUP BY mit ORDER BY

Im folgenden Beispiel wird zu jedem Produkttyp der Durchschnittspreis ermittelt, nach dem anschließend die Ergebnisse geordnet werden:

(Video) SQL WITH Clause | How to write SQL Queries using WITH Clause | SQL CTE (Common Table Expression)

USE AdventureWorks2012;GOSELECT ProductID, AVG(UnitPrice) AS [Average Price]FROM Sales.SalesOrderDetailWHERE OrderQty > 10GROUP BY ProductIDORDER BY AVG(UnitPrice);GO

K. Verwenden der HAVING-Klausel

Im ersten Beispiel wird eine HAVING-Klausel mit einer Aggregatfunktion gezeigt. Sie gruppiert die Zeilen in der SalesOrderDetail-Tabelle nach Produkt-ID und entfernt Produkte, deren durchschnittliche Bestellmenge mit 5 oder weniger angegeben ist. Im zweiten Beispiel wird eine HAVING-Klausel ohne Aggregatfunktionen gezeigt.

USE AdventureWorks2012;GOSELECT ProductID FROM Sales.SalesOrderDetailGROUP BY ProductIDHAVING AVG(OrderQty) > 5ORDER BY ProductID;GO

Diese Abfrage verwendet die LIKE-Klausel in der HAVING-Klausel.

USE AdventureWorks2012 ; GO SELECT SalesOrderID, CarrierTrackingNumber FROM Sales.SalesOrderDetail GROUP BY SalesOrderID, CarrierTrackingNumber HAVING CarrierTrackingNumber LIKE '4BD%' ORDER BY SalesOrderID ; GO 

L. Verwenden von HAVING und GROUP BY

Im folgenden Beispiel wird die Verwendung der Klauseln GROUP BY, HAVING, WHERE und ORDER BY in einer SELECT-Anweisung gezeigt. Sie erzeugt Gruppen und Summenwerte jedoch erst, nachdem alle Produkte entfernt wurden, deren Preise über 25 $ liegen und für die Bestellmengen unter 5 angegeben sind. Außerdem werden die Ergebnisse nach der ProductID-Spalte sortiert.

USE AdventureWorks2012;GOSELECT ProductID FROM Sales.SalesOrderDetailWHERE UnitPrice < 25.00GROUP BY ProductIDHAVING AVG(OrderQty) > 5ORDER BY ProductID;GO

M. Verwenden von HAVING mit SUM und AVG

Im folgenden Beispiel wird die SalesOrderDetail-Tabelle nach Produkt-ID gruppiert und nur die Produktgruppen eingeschlossen, für die Bestellungen mit einem Gesamtwert von mehr als $1000000.00 vorliegen und deren durchschnittliche Bestellmenge mit weniger als 3 angegeben ist.

USE AdventureWorks2012;GOSELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS TotalFROM Sales.SalesOrderDetailGROUP BY ProductIDHAVING SUM(LineTotal) > $1000000.00AND AVG(OrderQty) < 3;GO

Mit der folgenden Abfrage können Sie alle Produkte abfragen, für die Verkäufe im Gesamtwert von über $2000000.00 verzeichnet wurden:

USE AdventureWorks2012;GOSELECT ProductID, Total = SUM(LineTotal)FROM Sales.SalesOrderDetailGROUP BY ProductIDHAVING SUM(LineTotal) > $2000000.00;GO

Wenn Sie sicherstellen möchten, dass in die Berechnungen zu jedem Produkt mindestens 1.500 Artikel einfließen, entfernen Sie mit HAVING COUNT(*) > 1500 die Produkte, die Summen mit weniger als 1500 verkauften Artikeln zurückgeben. Die Abfrage sieht folgendermaßen aus:

USE AdventureWorks2012;GOSELECT ProductID, SUM(LineTotal) AS TotalFROM Sales.SalesOrderDetailGROUP BY ProductIDHAVING COUNT(*) > 1500;GO

N. Verwenden des INDEX-Optimiererhinweises

Im folgenden Beispiel werden zwei Möglichkeiten zum Verwenden des INDEX-Optimiererhinweises gezeigt. Das erste Beispiel zeigt, wie erzwungen werden kann, dass der Optimierer einen nicht gruppierten Index verwendet, um Zeilen aus einer Tabelle abzurufen. Im zweiten Beispiel wird ein Tabellenscan erzwungen, indem ein Index von 0 verwendet wird.

USE AdventureWorks2012;GOSELECT pp.FirstName, pp.LastName, e.NationalIDNumberFROM HumanResources.Employee AS e WITH (INDEX(AK_Employee_NationalIDNumber))JOIN Person.Person AS pp on e.BusinessEntityID = pp.BusinessEntityIDWHERE LastName = 'Johnson';GO-- Force a table scan by using INDEX = 0.USE AdventureWorks2012;GOSELECT pp.LastName, pp.FirstName, e.JobTitleFROM HumanResources.Employee AS e WITH (INDEX = 0) JOIN Person.Person AS ppON e.BusinessEntityID = pp.BusinessEntityIDWHERE LastName = 'Johnson';GO

M. Verwenden der OPTION- und GROUP-Hinweise

Im folgenden Beispiel wird gezeigt, wie die OPTION (GROUP)-Klausel in Verbindung mit einer GROUP BY-Klausel verwendet wird.

(Video) 58. DATEADD Function in SQL Server

USE AdventureWorks2012;GOSELECT ProductID, OrderQty, SUM(LineTotal) AS TotalFROM Sales.SalesOrderDetailWHERE UnitPrice < $5.00GROUP BY ProductID, OrderQtyORDER BY ProductID, OrderQtyOPTION (HASH GROUP, FAST 10);GO

O. Verwenden des UNION-Abfragehinweises

Im folgenden Beispiel wird der MERGE UNION-Abfragehinweis verwendet.

USE AdventureWorks2012;GOSELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHoursFROM HumanResources.Employee AS e1UNIONSELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHoursFROM HumanResources.Employee AS e2OPTION (MERGE UNION);GO

P. Verwenden einer einfachen UNION-Klausel

Das Resultset im folgenden Beispiel enthält den Inhalt der Spalten ProductModelID und Name der Tabellen ProductModel und Gloves.

USE AdventureWorks2012;GOIF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULLDROP TABLE dbo.Gloves;GO-- Create Gloves table.SELECT ProductModelID, NameINTO dbo.GlovesFROM Production.ProductModelWHERE ProductModelID IN (3, 4);GO-- Here is the simple union.USE AdventureWorks2012;GOSELECT ProductModelID, NameFROM Production.ProductModelWHERE ProductModelID NOT IN (3, 4)UNIONSELECT ProductModelID, NameFROM dbo.GlovesORDER BY Name;GO

Q. Verwenden von SELECT INTO mit UNION

Im folgenden Beispiel gibt die INTO-Klausel in der zweiten SELECT-Anweisung an, dass die ProductResults-Tabelle das endgültige Resultset der Union der angegebenen Spalten aus den Tabellen ProductModel und Gloves enthält. Beachten Sie, dass die Gloves-Tabelle in der ersten SELECT-Anweisung erstellt wird.

USE AdventureWorks2012;GOIF OBJECT_ID ('dbo.ProductResults', 'U') IS NOT NULLDROP TABLE dbo.ProductResults;GOIF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULLDROP TABLE dbo.Gloves;GO-- Create Gloves table.SELECT ProductModelID, NameINTO dbo.GlovesFROM Production.ProductModelWHERE ProductModelID IN (3, 4);GOUSE AdventureWorks2012;GOSELECT ProductModelID, NameINTO dbo.ProductResultsFROM Production.ProductModelWHERE ProductModelID NOT IN (3, 4)UNIONSELECT ProductModelID, NameFROM dbo.Gloves;GOSELECT ProductModelID, Name FROM dbo.ProductResults;

R. Verwenden von UNION in zwei SELECT-Anweisungen mit ORDER BY

Die Reihenfolge bestimmter Parameter, die mit der UNION-Klausel verwendet werden, ist von Bedeutung. Im folgenden Beispiel werden die ordnungsgemäße und die falsche Verwendung von UNION in zwei SELECT-Anweisungen veranschaulicht, in denen eine Spalte in der Ausgabe umbenannt werden soll.

USE AdventureWorks2012;GOIF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULLDROP TABLE dbo.Gloves;GO-- Create Gloves table.SELECT ProductModelID, NameINTO dbo.GlovesFROM Production.ProductModelWHERE ProductModelID IN (3, 4);GO/* INCORRECT */USE AdventureWorks2012;GOSELECT ProductModelID, NameFROM Production.ProductModelWHERE ProductModelID NOT IN (3, 4)ORDER BY NameUNIONSELECT ProductModelID, NameFROM dbo.Gloves;GO/* CORRECT */USE AdventureWorks2012;GOSELECT ProductModelID, NameFROM Production.ProductModelWHERE ProductModelID NOT IN (3, 4)UNIONSELECT ProductModelID, NameFROM dbo.GlovesORDER BY Name;GO

S. Verwenden von UNION mit drei SELECT-Anweisungen, wobei die Auswirkung von ALL und Klammern gezeigt wird

In den folgenden Beispielen wird UNION verwendet, um die Ergebnisse aus drei Tabellen zu kombinieren, wobei in allen Tabellen 5 identische Datenzeilen vorhanden sind. Im ersten Beispiel wird UNION ALL verwendet, um doppelte Datensätze anzuzeigen, und alle 15 Zeilen zurückgegeben. Im zweiten Beispiel wird UNION ohne ALL verwendet, um die doppelten Zeilen aus den kombinierten Ergebnissen der drei SELECT-Anweisungen zu löschen, und 5 Zeilen zurückgegeben.

Im dritten Beispiel wird ALL mit dem ersten UNION verwendet; das zweite UNION verwendet ALL nicht und ist in Klammern eingeschlossen. Da die zweite UNION-Anweisung in Klammern steht, wird sie zuerst verarbeitet; sie gibt 5 Zeilen zurück, weil die Option ALL nicht verwendet wird und Duplikate gelöscht werden. Diese 5 Zeilen werden mit den Ergebnissen der ersten SELECT-Anweisung mithilfe der UNION ALL-Schlüsselwörter kombiniert. Dabei werden die Duplikate in den beiden aus 5 Zeilen bestehenden Resultsets nicht gelöscht. Das Endergebnis enthält 10 Zeilen.

USE AdventureWorks2012;GOIF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NOT NULLDROP TABLE dbo.EmployeeOne;GOIF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NOT NULLDROP TABLE dbo.EmployeeTwo;GOIF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NOT NULLDROP TABLE dbo.EmployeeThree;GOSELECT pp.LastName, pp.FirstName, e.JobTitle INTO dbo.EmployeeOneFROM Person.Person AS pp JOIN HumanResources.Employee AS eON e.BusinessEntityID = pp.BusinessEntityIDWHERE LastName = 'Johnson';GOSELECT pp.LastName, pp.FirstName, e.JobTitle INTO dbo.EmployeeTwoFROM Person.Person AS pp JOIN HumanResources.Employee AS eON e.BusinessEntityID = pp.BusinessEntityIDWHERE LastName = 'Johnson';GOSELECT pp.LastName, pp.FirstName, e.JobTitle INTO dbo.EmployeeThreeFROM Person.Person AS pp JOIN HumanResources.Employee AS eON e.BusinessEntityID = pp.BusinessEntityIDWHERE LastName = 'Johnson';GO-- Union ALLSELECT LastName, FirstName, JobTitleFROM dbo.EmployeeOneUNION ALLSELECT LastName, FirstName ,JobTitleFROM dbo.EmployeeTwoUNION ALLSELECT LastName, FirstName,JobTitle FROM dbo.EmployeeThree;GOSELECT LastName, FirstName,JobTitleFROM dbo.EmployeeOneUNION SELECT LastName, FirstName, JobTitle FROM dbo.EmployeeTwoUNION SELECT LastName, FirstName, JobTitle FROM dbo.EmployeeThree;GOSELECT LastName, FirstName,JobTitle FROM dbo.EmployeeOneUNION ALL(SELECT LastName, FirstName, JobTitle FROM dbo.EmployeeTwoUNIONSELECT LastName, FirstName, JobTitle FROM dbo.EmployeeThree);GO

Weitere Informationen

CREATE TRIGGER (Transact-SQL)
CREATE VIEW (Transact-SQL)
DELETE (Transact-SQL)
EXECUTE (Transact-SQL)
Ausdrücke (Transact-SQL)
INSERT (Transact-SQL)
LIKE (Transact-SQL)
UNION (Transact-SQL)
EXCEPT und INTERSECT (Transact-SQL)
UPDATE (Transact-SQL)
WHERE (Transact-SQL)
PathName (Transact-SQL)
INTO-Klausel (Transact-SQL)

Videos

1. MS SQL tutorial on FOR XML and concatenation and STUFF function
(Accessible IT Software Tutorials)
2. MSSQL - Understanding Isolation Level By Example (Serializable)
(CodeCowboyOrg)
3. Transactions in SQL
(Internet Services and Social Networks Tutorials from HowTech)
4. How to use EXISTS / NOT EXISTS Logical Operator in SQL Server - SQL Server / TSQL Tutorial Part 125
(TechBrothersIT)
5. Using DISTINCT in SQL
(Database by Doug)
6. Querying SQL Server Data in Excel with a Parameter
(Dashboard Gear)
Top Articles
Latest Posts
Article information

Author: Mrs. Angelic Larkin

Last Updated: 30/05/2023

Views: 6423

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Mrs. Angelic Larkin

Birthday: 1992-06-28

Address: Apt. 413 8275 Mueller Overpass, South Magnolia, IA 99527-6023

Phone: +6824704719725

Job: District Real-Estate Facilitator

Hobby: Letterboxing, Vacation, Poi, Homebrewing, Mountain biking, Slacklining, Cabaret

Introduction: My name is Mrs. Angelic Larkin, I am a cute, charming, funny, determined, inexpensive, joyous, cheerful person who loves writing and wants to share my knowledge and understanding with you.